c# - What's the correct way to retrieve the DPI of secondary monitors? -


problem
on windows 8.1 (and newer) dpi setting per-monitor. can see in system settings primary display (laptop) set 125% dpi, , alternate display set 100% dpi. application written entirely in c#, , every api call i've tried results in incorrect dpi secondary monitor. keep in mind, calling method in initialization of process , have specified dpi aware in manifest:

(shcore.dll) setprocessdpiawareness(process_dpi_awareness::process_per_monitor_dpi_aware); 

attempts

(shcore.dll)  getdpiformonitor(hmonitor, monitor_dpi_type::mdt_effective_dpi, &dpix, &dpiy) 

(result 120 regardless of hmonitor handle)

(user32.dll) intptr dc = createdc(...); double logx = (double)getdevicecaps(dc, logpixelsx); double logy = (double)getdevicecaps(dc, logpixelsy); 

(result 120 regardless of device name createdc)

monitor layout
1 other thing confuses me, first monitor @ rect {0,0,1920,1080} second monitor @ {2400,0,2400,1350}, makes actual desktop size of {4800x1350} , virtual desktop size of {3840x1080}, there missing pixels between monitors can't account , don't understand.

                 screen 1    screen 2 actual pixels:   1920x1080   2400x1350 virtual pixels:  1536x864    1920x1080 top-left coord:  0x0         2400x0 actual dpi:      120 (125%)   96 (100%) returned dpi:    120 (125%)  120 (125%) 

another way can confirm displays different dpi, dragging center point of dpi aware application across boundary between monitors cause window change it's size consistent across displays (wpf default).

i've been fighting day already, , less hour after post question found answer. i'll leave question here if runs issue in future.

the correct method alternate monitor dpi's shcore.dll's getdpiformonitor method, tried above. problem setprocessdpiawareness not called enough make difference in windows/wpf application. tested creating new console application , new wpf application , reproducing minimal code. console application returned correct values, while wpf application returned incorrect values.

the solution add following manifest file:

<application xmlns="urn:schemas-microsoft-com:asm.v3">   <windowssettings>     <dpiaware xmlns="http://schemas.microsoft.com/smi/2005/windowssettings">true/pm</dpiaware>   </windowssettings> </application> 

the key here value of dpiaware tag, it's true/pm instead of true, makes difference.


Comments

Popular posts from this blog

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -