Trying to my Delphi 2010 application more user freindly in high DPI modes in Windows 7 I have been trying several methods to retrive PixelsPerInch and compare to 96. Alas, n
In case it helps someone, I have noticed that Screen->PrimaryMonitor->PixelsPerInch DOES change according to the display scaling.
Don't respond to the user's DPI setting.
Respond the user's font preference.
If you only respond to the user's DPI setting, then your form will not get bigger if the user uses a larger font than you used at design time, e.g.
By responding to font size (in pixels), you get high-DPI support for free (and you're being a good developer!):
13px
Windows 2000/XP (what you designed with)15px
(scale your designed form by 115%)15px
Windows Vista/7 (scale your designed form by 115%)16px
my home machine (scale your form by 123%)16px
my work machine (scale your designed form by 123%)You want to turn all your form's Scaled
property off; so they don't try to respond to dpi settings. You want the .NET WinForms equivalent of AutoScaleMode.Font.
And yes, once you've paid your taxes, and can handle different DPI settings, declare your application highDpi aware using a manifest - as other answers have given.
Don't use SetProcessDPIAware
, as it may be too late for DLLs that you depend on who already read the current DPI:
Note SetProcessDPIAware is subject to a possible race condition if a DLL caches dpi settings during initialization. For this reason, it is recommended that dpi-aware be set through the application (.exe) manifest rather than by calling SetProcessDPIAware.
You could have a look at the Registry value AppliedDPI at
HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI
Thanks to Andreas Rejbrand.
Because Delphi's IDE doesn't even provide a way to mark your application DPI-aware as David has shown you you need to make your own manifest and add stuff to it, and because going into DPI Aware mode means you will have to handle a lot of work yourself, you might find that it's just not worth it. I certainly abandoned the attempt after about 100 fruitless hours of work.
If your app used 100% Common Controls, and you didn't mind reworking all the others until they worked fine for you, then go for it.
Even Common-controls based controls like the Page control don't seem to work (at least their VCL wrappers don't work) well in a high-dpi environment once DPI virtualization is turned off.
Short version: Best practice these days is don't bother at all in VCL apps unless you absolutely must, and then, you may as well set aside time for rewriting and fixing every control in the VCL and every third party control, to work around the glitches.
Is your application DPI aware? If not, declare it so.
Edit:
If you really just want to detect the current setting, but don't want to enable DPI awareness for your whole application then maybe the best approach is to write a small (dpi aware) app whose sole job is to do this detection. Run it and transfer the result over to your main app. Or provide a launcher which detects and then runs the main app providing the setting as command line param. This of course only if there is no other API or "secret" call your application can make to determine the setting even when running DPI virtualized.
I think you need to mark your application as being high DPI aware by including this in your application manifest:
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
Details on declaring DPI awareness are given here.
It seems like you are currently falling back to what is called DPI Virtualization.