Jump to content
Sign in to follow this  
Gustav Schubert

Using WorkAreaHeight for MaxClientHeight

Recommended Posts

I wanted to precompute the max possible value of ClientHeight, based on Screen.WorkAreaHeight,

and I have tested on a normal HD-Screen and on a Surface tablet screen,

and I have been surprised that
- on the Surface screen WorkAreaHeight is always the same, no matter if TaskBar has collapsed,
- Screen.WorkAreaHeight is given in real pixels,
- whereas Height and ClientHeight are given in scaled pixels.

 

Normal Desktop HD Screen Report:

Handle.Scale = 1.0
Screen.WorkAreaHeight = 1040
MaxClientHeight = 1001

Screen-W-H = (1920, 1080)
(Form)-W-H = ( 616,  639)
Client-W-H = ( 600,  600)

MaxClientHeight :=  wah - Round(scale *(h - ch));
           1001 := 1040 - Round(1.0 *(639 - 600));

mch = MaxClientHeight / scale = 1001

Surface-Pro Screen Report:

Handle.Scale = 2.0
Screen.WorkAreaHeight = 1824
MaxClientHeight = 876

Screen-W-H = (2736, 1824)
(Form)-W-H = ( 613,  636)
Client-W-H = ( 600,  600)

MaxClientHeight :=  wah - Round(scale *(h - ch));
           1752 := 1824 - Round(2.0 *(636 - 600));

mch = MaxClientHeight / scale = 876

Report generating code:

procedure TForm1.UpdateReport;
var
  scale: single;
  h:Integer;
  ch: Integer;
  wah: Integer;
  MaxClientHeight: Integer;
  mch: Integer;
begin
  scale := Handle.Scale;
  h := Height;
  ch := ClientHeight;
  wah := Screen.WorkAreaHeight;
  MaxClientHeight := Screen.WorkAreaHeight - Round(scale *(h - ch));
  mch := Round(MaxClientHeight / scale);

  { ClientHeight := mch; // this is the intended use of mch }
  { mch is the actual MaxClientHeight to be used. }

  { ML is a TStringList }
  ML.Clear;
  ML.Add(Format('Handle.Scale = %.1f', [scale]));
  ML.Add(Format('Screen.WorkAreaHeight = %d', [wah]));
  ML.Add(Format('MaxClientHeight = %d', [MaxClientHeight]));
  ML.Add('');
  ML.Add(Format('Screen-W-H = (%d, %d)', [Screen.Width, Screen.Height]));
  ML.Add(Format('(Form)-W-H = (%d, %d)', [Width, Height]));
  ML.Add(Format('Client-W-H = (%d, %d)', [ClientWidth, ClientHeight]));

  ML.Add('');
  ML.Add(Format('MaxClientHeight :=  wah - Round(scale *(h - ch));', []));
  ML.Add(Format('           %d := %d - Round(%.1f *(%d - %d));',
    [MaxClientHeight, wah, scale, h, ch]));
  ML.Add('');
  ML.Add(Format('mch = MaxClientHeight / scale = %d', [mch]));

  { Memo is a component on the form }
  Memo.Text := ML.Text;
end;

What do you think about Screen.WorkAreaHeight?

Is this the best thing to use?

How should I compute the maximum of ClientHeight that can be visible on a given screen?

Edited by Gustav Schubert
typo

Share this post


Link to post

TScreen.WorkAreaHeight is available in Vcl and in FMX. The Vcl help has slightly more info, but it does not mention whether the value is ever updated or not.

 

Found out that, if you change the rotation of the form on the Surface tablet, it does not update. If you change the taskbar mode (Taskleiste automatisch ausblenden, available in taskbar context menu on Surface Pro), it does NOT update either. Any change is only reflected after restart of app. And since the implementation hides behind TPlatformServices.Current.Something it is not easy to find out. Back to square 2.

 

Edit 1: It seems I have to call Screen.UpdateDisplayInformation manually, but when?

Edited by Gustav Schubert
progress

Share this post


Link to post

In FMX have you checked the Application Events with OrientationChange under FMX.Platform ?

They fire  on iOS and Android,  Not sure about Wintel .

Edited by Rollo62

Share this post


Link to post

On the desktop I call Screen.UpdateDisplayInformation just before I need it, it works for me.


But the next problem I found with Screen.WorkAreaHeight is that the units (real pixel or scaled pixel) are different between the platforms.


Surface Pro = real pixels given (Scale = 2.0)
My Desktop = cannot tell (because Scale = 1.0)
Retina iMac = scaled pixels returned (Scale = 2.0)

 

So, on Windows Screen.WorkAreaHeight and ClientHeight are NOT using the same units, on Mac they are given in same units, but what should it be by design?

 

( I have a workaround that in my test App. )

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×