Programming => General => Topic started by: RedOctober on April 06, 2020, 04:15:37 pm

Title: Main window behind Taskbar at Startup
Post by: RedOctober on April 06, 2020, 04:15:37 pm
I've been fighting with this for about a week.  I want my main form to be centered on the screen, not maximized, and sized to account for the task bar, regardless of it's location.  Making the form a specific "too small" size then just set position to WorkAreaCenter is simple enough, but that means I'm not using all the screen real estate available which in my case..I need every possible pixel to be available.   No matter what I do with

Monitor.WorkareaRect.Width  or Monitor.WorkareaRect.Height 
my main window always is about 8 pixels too large and behind the task bar.

By playing with form fsMaximized versus fsNormal I have determined that the Screen.x and Monitor.x are lying. They say that the task bar is a full 40 pixels high, but it's not.  It's actually only 32 pixels high.  So I have to go burrowing through all the rabbit holes trying various ways to calculate the true height/width of the task bar and position my main window accordingly.  I am using Lazarus 1.8.4, FPC 3.0.4 on Windows server 2016, and my monitor is a SuperWide 2560 wide by 1080 high.

This might help, if there was a Lazarus equivalent to it: (

What is the Lazarus way of accomplishing this simple task?  Thanks in advance for any help you can provide.
Title: Re: Main window behind Taskbar at Startup
Post by: GetMem on April 06, 2020, 07:00:14 pm
The code in the link( compiles if you add to uses JwaWindows, ShellApi and change AppData to @AppData. I did not checked the functionality though.
Title: Re: Main window behind Taskbar at Startup
Post by: jamie on April 06, 2020, 11:35:34 pm
I always test the form visible position during the OnCreate and make changes if needed..

This is important if you do a mass move of your application that also moves configuration files along with it.
Title: Re: Main window behind Taskbar at Startup
Post by: RedOctober on April 09, 2020, 03:49:02 pm
I had to resort to this madness:   I created a maximized "Screen Sizer" window that is invisible (Alphablend on, Alphablend value zero)  I display it to screen for a microsecond and read the size of it.  It gives reliable information, so I store it and use it for sizing my "real" main window, which has maximum width and height set, but not minimum.

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.LoadDefaults;
  2. var
  3.   frmScrnSizer: TfrmScrnSizer;   hnd: Boolean;
  4. begin
  5. ...
  7.   frmScrnSizer := nil;
  8.   try
  9.     frmScrnSizer := TfrmScrnSizer.Create(Self);
  10.     frmScrnSizer.Show;
  12.     GV.AppProps.viz_scrn_wdt := frmScrnSizer.Width;
  13.     GV.AppProps.viz_scrn_hgt := frmScrnSizer.Height;
  14.   finally
  15.     frmScrnSizer.Free;
  16.   end;
  18.   if GV.AppProps.viz_scrn_hgt < 1000 then
  19.     Height := GV.AppProps.viz_scrn_hgt;
  21.   if GV.AppProps.viz_scrn_wdt < 1280 then
  22.     Width := GV.AppProps.viz_scrn_wdt;
  23. ...
Title: Re: Main window behind Taskbar at Startup
Post by: lucamar on April 09, 2020, 05:35:17 pm
I had a similar problem and after some testing I found that only Monitor.WorkareaRect gave the correct measure.

One of my test was to call at different times this small proc:

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.ShowMeasures(const header: String = '');
  2. var
  3.   fmtMeasures: String =
  4.     'Screen:'+LineEnding
  5.     + '- Width,Height: %d x %d'+LineEnding
  6.     + '- Desktop W/H : (%d,%d) %d x %d'+LineEnding
  7.     + '- Workarea W/H: (%d,%d) %d x %d'+LineEnding
  8.     +'Monitor:'+LineEnding
  9.     + '- L,T WxH     : (%d,%d)  %d x %d'+LineEnding
  10.     + '- Workarea    : (%d,%d) %d x %d'+LineEnding
  11.     +'Form:'+LineEnding
  12.     + '- L,T WxH     : (%d,%d) %d x %d'+LineEnding
  13.     + '- ClientRect  : (%d,%d) %d x %d';
  14.   MWARect: TRect;
  15. begin
  16.   MWARect := Monitor.WorkareaRect;
  17.   if header <> '' then
  18.     fmtMeasures := header + LineEnding + fmtMeasures;
  19.   ShowMessageFmt(fmtMeasures,
  20.       [Screen.Width, Screen.Height,
  21.        Screen.DesktopLeft, Screen.DesktopTop,
  22.        Screen.DesktopWidth, Screen.DesktopHeight,
  23.        {-----}
  24.        Screen.WorkAreaLeft, Screen.WorkAreaTop,
  25.        Screen.WorkAreaWidth, Screen.WorkAreaHeight,
  26.        {=====}
  27.        Monitor.Left, Monitor.Top, Monitor.Width, Monitor.Height,
  28.        MWARect.Left, MWARect.Top, MWARect.Width, MWARect.Height,
  29.        {=====}
  30.        Left, Top, Width, Height,
  31.        ClientRect.Left, ClientRect.Top, ClientRect.Width, ClientRect.Height
  32.       ]);
  33. end;

That shows, for example the dialog in the attached image. Note, in particular, that the form measures don't take into account the size of the non-client area (borders, etc.) so the form's width and height are the same than ClientWidth and ClientHeight, which is why the image has to be 512 pixels high though the reported Height is 480 pixels.

But all this is in Linux (gtk2); I don't know whether it applies to your system.
TinyPortal © 2005-2018