Recent

Author Topic: Cannot set width and height of TForm in OnShow  (Read 469 times)

anse

  • New Member
  • *
  • Posts: 10
Cannot set width and height of TForm in OnShow
« on: March 21, 2025, 08:20:09 pm »
On Ubuntu 22.04 with Lazarus 3.8 and gtk2 widgetset, I have some (not all) forms which I cannot set programmatically to some width + height value. The code in OnShow is simple:

Code: Pascal  [Select][+][-]
  1. procedure TMyForm.FormShow(Sender: TObject);
  2. begin
  3.   Width := WidthFromPreviousSetting; // 1000
  4.   Height := HeightFromPreviousSetting; // 500
  5. end;
  6.  

I can see the form is resized for a millisecond to 1000 x 500, and then magically the OnResize event is fired where I can see the width and height are both reset to their design-time-values 600 x 300.

In the same millisecond of that magic OnResize call I see such a warning in the shell (I am starting the app from a shell):
Quote
"Pango-WARNING **: 19:37:46.261: Invalid UTF-8 string passed to pango_layout_set_text()

I already googled around and found a few hints to form properties, so here they are:
  • AutoSize is False
  • BorderIcons is biMaximize, biMinimize, biSystemMenu
  • BorderStyle is bsSizable
  • Constraints.Min/MaxWidth are 0
  • Constraints.Min/MaxHeight are 0
  • FormStyle is fsNormal
  • Position is poMainFormCenter (tested all other values - does not make any difference)
  • Scaled is True
  • WindowState is wsNormal

This never happens in the main form, only in forms created within the running app.

The forms are converted by hand from a Delphi application. I have the gutt feeling I am overseeing some important thing.

wp

  • Hero Member
  • *****
  • Posts: 12757
Re: Cannot set width and height of TForm in OnShow
« Reply #1 on: March 22, 2025, 12:43:43 am »
I tested this on Ubuntu 22.04/gtk2 with Laz/main and did not see the described behaviour. I guess that there is something in your code of these forms which resize them again after your OnShow handler. Add a handler for the OnResize event, put some dummy code in it and set a breakpoint. Then study the stack trace when the application stops at this breakpoint, maybe you can find the guilty code line down the trace. (But note that this beakpoint will become active several times).

BTW, does the same happen also when you set the form width and height in the OnCreate event? This would be the more natural place for me than the OnShow event.

anse

  • New Member
  • *
  • Posts: 10
Re: Cannot set width and height of TForm in OnShow
« Reply #2 on: March 22, 2025, 01:58:01 pm »
It seems that Application.Idle calls some delayed resizing. I hope this is the right callstack:

Code: Text  [Select][+][-]
  1. #0 TMyform.FormResize(TMyform($0000765655C5FD90), TObject($0000765655C5FD90)) at myform.pas:384
  2. #1 TCONTROL.DOONRESIZE(TCONTROL($0000765655C5FD90)) at control.inc:1363
  3. #2 TSCROLLINGWINCONTROL.DOONRESIZE(TSCROLLINGWINCONTROL($0000765655C5FD90)) at scrollingwincontrol.inc:67
  4. #3 TCUSTOMFORM.DELAYEDEVENT(TCUSTOMFORM($0000765655C5FD90), 0) at customform.inc:726
  5. #4 TAPPLICATION.PROCESSASYNCCALLQUEUE(TAPPLICATION($0000765657CE7B50)) at application.inc:1085
  6. #5 TAPPLICATION.IDLE(TAPPLICATION($0000765657CE7B50), True) at application.inc:447
  7. #6 TCUSTOMFORM.SHOWMODAL(TCUSTOMFORM($0000765655C5FD90)) at customform.inc:3049
  8.  

And yes, setting the form's width and height in OnCreate fixes the issue! That's at least nice. Probably the above delayed event handling is only done when width/height were modified in OnShow, but that's just a guess.

Now why I was setting the width/height in OnShow and not in OnCreate: if I recall right I did that due to high DPI issues, to prevent the custom width/height getting scaled after OnCreate, which was not happening after OnShow.

wp

  • Hero Member
  • *****
  • Posts: 12757
Re: Cannot set width and height of TForm in OnShow
« Reply #3 on: March 22, 2025, 02:54:31 pm »
I hope this is the right callstack: [...]
Looks rather innocent...

Now why I was setting the width/height in OnShow and not in OnCreate: if I recall right I did that due to high DPI issues, to prevent the custom width/height getting scaled after OnCreate, which was not happening after OnShow.
I never can remember when scaling happens... If the stored WidthFromPreviousSetting is not scaled in OnCreate, you can scale it manually:
Code: Pascal  [Select][+][-]
  1. procedure TMyForm.FormCreate(Sender: TObject);
  2. begin
  3.   Width := Scale96ToForm(WidthFromPreviousSetting);
  4.   Height := Scale96ToForm(HeightFromPreviousSetting);
  5. end;
"Scale96ToForm" means: Assuming that the provided parameter is for 96 ppi, scale it to the ppi settings of the form. There is also a reverse "ScaleFormTo96" which scales the current dimension back to 96ppi.

anse

  • New Member
  • *
  • Posts: 10
Re: Cannot set width and height of TForm in OnShow
« Reply #4 on: March 22, 2025, 06:38:12 pm »
Thanks a lot, that's a good advice.

As I'm parallely running Lazarus on Windows on a 120 DPI screen, I'd like to mention there's also ScaleDesignToForm() and ScaleFormToDesign(), which respects the stored form properties DesignTimePPI (and/or PixelsPerInch?).

 

TinyPortal © 2005-2018