Recent

Author Topic: Titlebarheight  (Read 320 times)

winni

  • Sr. Member
  • ****
  • Posts: 436
Titlebarheight
« on: November 06, 2019, 08:27:54 pm »
Hi!

On gtk2 and other widgetsets this is not implemented:

Code: Pascal  [Select]
  1. TBarHeight := GetSystemMetrics(SM_CYCAPTION);

And a lot of docs say that it is impossible to figure out.

So let's do the impossible.

Code: Pascal  [Select]
  1. function TitleBarHeight (Form: TForm) : Integer;
  2. var ws : TWindowState;
  3.     oldheight : integer;
  4. begin
  5. ws := Form.WindowState;
  6. if ws <> wsMaximized then
  7.   begin
  8.    oldHeight := Form.Height;
  9.    Form.WindowState := wsMaximized;
  10.    repeat
  11.    Application.ProcessMessages; // let Form expand
  12.    until Form.Height <> oldHeight; // but one ProcessMessages is [b]not [/b]enough!
  13.    end;
  14. result := Screen.Height -Form.Height;
  15. if ws <> wsMaximized then
  16.   begin
  17.   Form.WindowState := ws; // and back again
  18.   Application.ProcessMessages;
  19.   end;
  20. end;                  
  21.  
  22.  

Works ok with linux/gtk2. Don't know about other widgetsets.

Winni


lucamar

  • Hero Member
  • *****
  • Posts: 2081
Re: Titlebarheight
« Reply #1 on: November 06, 2019, 10:10:36 pm »
Instead of:
  Screen.Height
you should use:
  Form.Monitor.WorkAreaRect.Height
It'll encompass more situations; like, say, a Gnome desktop with top and/or bottom system-bars

Note also that a form might be full-Height yet not be maximized, in which case your
Code: Pascal  [Select]
  1.  repeat
  2.    Application.ProcessMessages;
  3.    until Form.Height <> oldHeight;
will produce a infinite loop. You should check for that situation.
« Last Edit: November 06, 2019, 10:12:51 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

winni

  • Sr. Member
  • ****
  • Posts: 436
Re: Titlebarheight
« Reply #2 on: November 06, 2019, 11:12:25 pm »
Two times right:

Form.Monitor.WorkAreaRect.Height

may be needed for situations that I don't know: System-bar at bottom of KDE screen, but reports correct height.

It was so easy then, when we had 640 x 480 pixel .....

And the rare sitation that the height is = height as maximized is solved with a loop counter:

Code: Pascal  [Select]
  1. var count : integer = 0;
  2. ...
  3.    repeat
  4.    Application.ProcessMessages; // let Form expand
  5.    inc (Count);
  6.    until (Form.Height <> oldHeight) or (count > 10);
  7.  
  8.  

I kept trace who often the loop is done, interesting enough:

If you start the function in a startup situation, it needs sometimes  2 loops and sometimes only 1 loop.
If you start it when the app is not busy, then it needs only 1 loop.

Thanks for the hints!

Winni