views:

783

answers:

2

Is there any way to stop the user resizing the form?

Currently I am using:

When form size changed....

MainForm.Height := 761;
MainForm.Width := 777;

But this looks horrible as it flickers as the user tries to change the form size.

+12  A: 

[Fixing the size] is easy, you have two options.

  1. delphi forms have a BorderStyle property and a BorderIcons property. if you set BorderStyle to bsDialog, and BorderIcons to biSystemMenu only, user can not resize the form.

  2. you can specify value to Constraints property. if you write the same number to MinWidth and MaxWidth, the width will be fixed.

preventing move is more tricky. i can come up with only these solutions now

  1. set BorderStyle to bsNone. you will need to draw the form caption yourself, if needed.

  2. write a message handler to WM_NCHITTEST, call inherited first, then check the Message.Result for HTCAPTION. if it is HTCAPTION, set it to HTCLIENT instead. this way, you fool windows to think the user didn't click on caption, so he will not be able to drag. please try if the user can still move the window opening the system menu, and choosing Move. if so, you have to hide the system menu too (BorderIcons)

Answer found here.

Paul Sasik
+1 I think the easiest way to accomplish this is using constraints.
johnny
Constraints have one really annoying bug though: If you set `MinWidth` and `MaxWidth` and `MinHeight` and `MaxHeight` respectively to the same values, and try to resize the form with the left or top border, then the form will not be resized but moved. Setting `bsSingle` doesn't have this problem, and is better (consistent) from a UI perspective as well. A form that isn't resizeable shouldn't have the resize border either.
mghie
@mghie. > ..."then the form will not be resized but moved"... That's a VCL bug which seems to have been fixed. See QC71595 - http://qc.embarcadero.com/wc/qcmain.aspx?d=71595 for a possible workaround.
Sertac Akyuz
@Sertac: Yes, it is a VCL bug that has been in since constraints were introduced, and which hasn't been fixed in over ten years. My answer to this question has another workaround (with no need to change the VCL) that I have been using. Though it's great they seem to have fixed it finally.
mghie
+3  A: 

If you want your form to not resize at all, then setting the form border style to bsSingle is the right thing to do, as then the mouse cursor will not change to one of the sizing cursors when moved over the form borders, so it is obvious to the user that this form can not be resized.

If you want to set a minimum and / or a maximum size for the form, then bsSizeable is the correct border style, and you can use the Constraints of the form to specify the limits. There is however the problem that the Constraints property doesn't prevent the resizing of the form, it only causes the sizes to be adjusted after the fact so that the limits are not violated. This will have the negative side effect that sizing the form with the left or upper border will move it. To prevent this from happening you need to prevent the resizing in the first place. Windows sends the WM_GETMINMAXINFO message to retrieve the minimum and maximum tracking sizes for a top level window. Handling this and returning the correct constraints fixes the moving form issue:

type
  TForm1 = class(TForm)
  private
    procedure WMGetMinMaxInfo(var AMsg: TWMGetMinMaxInfo);
      message WM_GETMINMAXINFO;
  end;

// ...

procedure TForm1.WMGetMinMaxInfo(var AMsg: TWMGetMinMaxInfo);
begin
  inherited;
  with AMsg.MinMaxInfo^ do begin
    ptMinTrackSize := Point(Constraints.MinWidth, Constraints.MinHeight);
    ptMaxTrackSize := Point(Constraints.MaxWidth, Constraints.MaxHeight);
  end;
end;
mghie