Recent

Author Topic: Per Monitor DPI Awareness  (Read 1125 times)

bastynator

  • New Member
  • *
  • Posts: 16
Per Monitor DPI Awareness
« on: March 31, 2020, 04:23:00 pm »
Hey everyone,

i'm developing an application that should be dpi aware per monitor. That means, a user has two monitors 1: 1080p windows scaling 100% 2: 4k UHD windows scaling 300%
I already extended the .exe.manifest

Code: Pascal  [Select][+][-]
  1. <dpiAware>true/pm</dpiAware>

And i'm listening for dpi-change messages from windows:

Code: Pascal  [Select][+][-]
  1. const
  2.   WM_DPICHANGED = $02E0;
  3. var
  4.   PrevWndProc: WNDPROC;
  5. // ...
  6. function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam):LRESULT; stdcall;
  7. var AMessage: TLMessage;
  8. begin
  9.   FillChar(AMessage, SizeOf(TLMessage), 0);
  10.   AMessage.msg := uMsg;
  11.   AMessage.wParam := wParam;
  12.   AMessage.lParam := lParam;
  13.   if AMessage.msg = WM_DPICHANGED then begin
  14.     ADPI := lo(lo(AMessage.wParam));
  15.     // Do stuff with new dpi value, e.g. set control font size
  16.     exit;
  17.   end;
  18. end;
  19. // ...
  20. constructor TMyForm.Create(AOwner: TComponent);
  21. begin
  22.   inherited Create(AOwner);
  23.   PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Self.Handle,GWL_WNDPROC,PtrInt(@WndCallback)));
  24. end;
  25.  

That works well for all my ui-elements. But the dpi-change seems to be ignored for the title-bar, menus, popup-menus and system-dialogs (e.g. file-open, file-save)
I checked out this demo: https://wiki.lazarus.freepascal.org/High_DPI but sadly this is not per-monitor aware. That means, the window is blurry once its moved to a monitor with different scaling.
I fear there is a problem with lazarus and/or the LCL implementation... Please prove me, i'm wrong  :)

Has anyone experience with per-monitor dpi-awaremess?

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Per Monitor DPI Awareness
« Reply #1 on: March 31, 2020, 04:51:20 pm »
Forget this code. Simply check the "Use LCL scaling" box in the project options, and two lines below, in the "DPI awareness" combobox, select one of the "per monitor" options.

See https://wiki.lazarus.freepascal.org/High_DPI#High_DPI_in_Lazarus_1.8_and_above

bastynator

  • New Member
  • *
  • Posts: 16
Re: Per Monitor DPI Awareness
« Reply #2 on: April 01, 2020, 09:08:49 am »
I tried the steps on the wiki but i didn't get the expected result. The app looks great and scaled correctly on startup. But gets scaled by windows which looks blurry when it's moved to a monitor with different scaling.
And this is also true for lazarus itself as well as the CPickSniff example.
Lazarus-apps seem to adopt the scaling of the monitor they start. In my example all apps look great on 120%, so they are scaled up correctly. But when i move them to a monitor with 100% scaling windows scales lazarus-apps down to 100% which results in blurry appearance.
I don't think this is a correct per-monitor dpi-awareness, or do i miss something? I would expect that per-monitor means the app gets a dpi-change-message and scales the form during runtime (not just on startup).
It seams like lazarus supports dpi-awareness, but not per-monitor.
Don't you think?

I attached a screenshot that shows lazarus and CPickSniff moved from 120% to a 100% scaled monitor. That should demonstrate what i mean.

Do you know the git-bash for example? This console-app looks great on all monitors, it scales during runtime.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: Per Monitor DPI Awareness
« Reply #3 on: April 01, 2020, 09:55:54 am »
I don't think this is a correct per-monitor dpi-awareness, or do i miss something? I would expect that per-monitor means the app gets a dpi-change-message and scales the form during runtime (not just on startup).
It seams like lazarus supports dpi-awareness, but not per-monitor.
Don't you think?

I checked the LCL code and it does handle WM_DPICHANGED. So there is probably another problem.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9867
  • Debugger - SynEdit - and more
    • wiki
Re: Per Monitor DPI Awareness
« Reply #4 on: April 01, 2020, 02:47:29 pm »
Maybe test with Lazarus svn trunk.

I just tested, and I can move a window from 150% to 100% with no issues.

I tested the IDE itself, if it would follow the DPI. And it works, in both directions. I can start the IDE on the 150 DPI monitor and  move to 100%. Or the other way round.

I did note one issue. If I start the IDE (none docked), so that the IDE bar goes on the 100% monitor, but the project inspector goes on the 150%, then the project inspector is not scaled at start up. But it does get scaled, as soon as I move it within the screen on which it is.
I have not further tested that. If you can reproduce that, it is worth to report it.

 

TinyPortal © 2005-2018