0

I need to create FMX form dynamically with a fixed width and height, but I get bigger size when removing borders or setting to BorderStyle=Single.

When setting BorderStyle to None or Single, even setting a fixed ClientWidth and ClientHeight, the size of the form keeps the original Windows border, so If I create a Sizeable (Default) Form, both of forms remains with the same size, incorrectly.

Please see the image to better understand:

enter image description here

Using Delphi 10.4 and Windows 11, but I have tested in others environments and it has the same problem.

var
  Form: TForm;
  Shape: TRectangle;
begin
  //Form with Border Sizeable
  Form := TForm.CreateNew(Application);
  Form.BorderStyle := TFmxFormBorderStyle.Sizeable;
  Form.Fill.Color := TAlphaColors.Yellow;
  Form.Fill.Kind := TBrushKind.Solid;

  Form.ClientWidth := 300;
  Form.ClientHeight := 300;

  Shape := TRectangle.Create(Form);
  Shape.Parent := Form;
  Shape.SetBounds(0, 0, 300, 300);

  Form.Show;

  //Form with Border Single
  Form := TForm.CreateNew(Application);
  Form.BorderStyle := TFmxFormBorderStyle.Single;
  Form.Fill.Color := TAlphaColors.Yellow;
  Form.Fill.Kind := TBrushKind.Solid;

  Form.ClientWidth := 300;
  Form.ClientHeight := 300;

  Shape := TRectangle.Create(Form);
  Shape.Parent := Form;
  Shape.SetBounds(0, 0, 300, 300);

  Form.Show;

  //Form with Border None
  Form := TForm.CreateNew(Application);
  Form.BorderStyle := TFmxFormBorderStyle.None;
  Form.Fill.Color := TAlphaColors.Yellow;
  Form.Fill.Kind := TBrushKind.Solid;

  Form.ClientWidth := 300;
  Form.ClientHeight := 300;

  Shape := TRectangle.Create(Form);
  Shape.Parent := Form;
  Shape.SetBounds(0, 0, 300, 300);

  Form.Show;
end;

Doing the same thing in form designer, the problems does not occurs.

If I set Width and Height instead of ClientWidth and ClientHeight when BorderStyle = None, it works, but when I'm setting BorderStyle = Single, the problem occurs, and in this case I can't set Width and Height because I still have form border.

In VCL environment, this works exactly as expected, where the real window size (considering borders) are different by changing border, keeping always ClientRect (ClientWidth and ClientHeight) the same.

Expected (running in VCL with same sizes): All forms have same ClientRect, no matter the border changes.

enter image description here

4
  • And the same problem occurs when setting Form.Position := TFormPosition.ScreenCenter. The form is shown at the designed position (not aligned at Screen center) Commented May 3, 2023 at 13:46
  • I get similar results. But what's your actual question? Commented May 3, 2023 at 15:02
  • I need to create form dynamically with a fixed width and height, but I get bigger size when removing borders. Commented May 3, 2023 at 15:36
  • I have now tested the same code in Delphi 12 and the problem still occurs. Commented Dec 12, 2023 at 23:23

1 Answer 1

0

I think that this is a bug that ought to be reported. But here is a workaround, albeit one that has a couple of values hard-coded.

I take it that you want to give a fixed size to the client area of the form. Most of the code below is just for testing purposes, so the key part is only about nine lines.

var
  Form: TForm;

  function CreateForm(bs:TFMXFormBorderStyle; X,Y:Integer; w:Integer=300; h:Integer=300):TForm; //X and Y are just for testing purposes.
  var   Line:   TLine;  //Both variables are just for testing purposes.
    Shape: TRectangle;

    procedure AddLabel(Y:Single; s:string; Value:Integer);  //Only for testing purposes
    var Lbl:    TLabel;
    begin
      Lbl:=TLabel.Create(Result);
      with Lbl do begin
        Parent:=Result;
        Position.Y:=Y;
        Position.X:=150;
        Text:=s+'='+Value.ToString;
      end;
    end;

  begin
    Result:=TForm.CreateNew(Application);
    with Result do begin
      BorderStyle:=bs;
      case bs of
        TFMXFormBorderStyle.None:       begin Width:=w;         Height:=h;       end;
        TFMXFormBorderStyle.Single:     begin Width:=w+6;       Height:=h+29;    end;
        TFMXFormBorderStyle.Sizeable:   begin ClientWidth:=w;   ClientHeight:=h; end;
      end;
    end;

    //Everything below here is just for testing purposes.

    with Result do begin
      Fill.Color := TAlphaColors.Yellow;
      Fill.Kind := TBrushKind.Solid;
      Left:=X; Top:=Y;
    end;

    Shape := TRectangle.Create(Result);
    Shape.Parent := Result;
    Shape.SetBounds(0, 0, 300, 300);

    Line:=TLine.Create(Result);
    with Line do begin
      Parent:=Shape;
      ALign:=TAlignLayout.Contents;
    end;

    Result.Show;    //This needs to come before getting the widths and heights for the labels.

    AddLabel(20,'Width',        Result.Width);
    AddLabel(40,'Height',       Result.Height);
    AddLabel(60,'ClientWidth',  Result.ClientWidth);
    AddLabel(80,'ClientHeight', Result.ClientHeight);
  end;

begin
  //Form with Border Sizeable
  Form := CreateForm(TFmxFormBorderStyle.Sizeable,1200,30);

  //Form with Border Single
  Form := CreateForm(TFmxFormBorderStyle.Single,800,30);

  //Form with Border None
  Form := CreateForm(TFmxFormBorderStyle.None,300,30);
end;
Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately this solution doesn't work because you fixed sizes for the borders (6 and 29). This size varies depending on the version of Windows and the theme that is configured. But I agree this is a bug.
Unfortunately the form only gains its final size when you show it. Would it be acceptable to show it then adjust the size? What about showing it off-screen, adjusting the size, then putting it where you want it on-screen?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.