Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting custom DPI percentage in Delphi

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, no matter what I tried I always get 96. My questions are:

  1. What is the best practice to get custom DPI mode?
  2. Is the fact I am getting a constant 96 no matter what I what the percebtage is means I missing somthing?

Here is what I had tried

dpiX := Form1.PixelsPerInch

and

dpiX := Screen.PixelsPerInch

and finally:

D2DFactoryOptions.DebugLevel := D2D1_DEBUG_LEVEL_NONE;
pD2DFactoryOptions := @D2DFactoryOptions;
if D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    IID_ID2D1Factory,
    PD2DFactoryOptions,
    D2DFactory
    ) <> S_OK then exit;
D2DFactory.GetDesktopDpi(dpiX, dpiY)

Care to guess? that's right dpiX is a constant 96 in 100%, 125% and 150%

Please advice.

like image 381
asafadd Avatar asked Aug 08 '11 14:08

asafadd


4 Answers

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.

like image 193
David Heffernan Avatar answered Oct 23 '22 13:10

David Heffernan


You could have a look at the Registry value AppliedDPI at

HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI

Thanks to Andreas Rejbrand.

like image 42
Dmitry Avatar answered Oct 23 '22 13:10

Dmitry


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.

like image 4
Heinrich Ulbricht Avatar answered Oct 23 '22 12:10

Heinrich Ulbricht


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.

like image 2
Warren P Avatar answered Oct 23 '22 13:10

Warren P