0
votes

Sorry I didn't put a specific issue title.

My dev environment is Windows 7 with Visual Studio 2010. The product targets for Windows 7, 8 and 10.

Question 1: How could I get the current DPI settings?

The code below always returns 96 which is 100% DPI scale.

_dpiX = GetDeviceCaps(hdc, LOGPIXELSX);

Question 2: How could I get the actual resolution?

I have tried to use GetSystemMetrics with different options, they all return the same value which is the scaled resolution. For example, with an actual resolution 1920*1080 and 175% DPI, they all return 1097*617.

GetSystemMetrics(SM_CXFULLSCREEN)
GetSystemMetrics(SM_CXSCREEN)
GetSystemMetrics(SM_CXVIRTUALSCREEN)

Question 3: Can I set the app not to use DPI visualization feature?

We have a work around involving tick the 'disable display scaling on high DPI settings' option in Properties->Compatibility and use 'change settings for all users'. I have set the project DPIAwareness to true in Visual Studio, but it doesn't do anything.

Edit: Some people say if the product is set to DPI aware, it won't get DPI visualization. In my case, it's a GUI program passing some command arguments to another executable. I have set the executable DPIAwareness to true in my project. But nothing is done with the GUI. So if the GUI is not DPI aware, and it starts the other processes, are the other processes also not DPI aware?

2
As long as you don't answer question 3, you don't care about 1 and 2. Lots and lots of ways to find this out by yourself, Google "windows enable dpiawareness".Hans Passant
The truth is if I can solve question 3, I probably just solve the issue. The core idea about question 3 is how I can disable DPI visualization within my project. Someone says set DPIAwareness to true would disable it. But it doesn't seem to work.Jerry

2 Answers

0
votes

for question 1, have you tried this?

monitorhandle = MonitorFromWindow(winH, MONITOR_DEFAULTTONEAREST)

winH is the handle of your program's window

MONITOR_DEFAULTTONEAREST = 2

then:

GetDpiForMonitor(monitorhandle, MDT_EFFECTIVE_DPI, PointerToX, PointerToY)

MDT_EFFECTIVE_DPI = 0

That will retrieve the DPI settings in PointerToX and PointerToY

You can then divide by 96 if you need the Windows scaling value (*100 for a percentage of course)

I am surprised if setting SetProcessDpiAwareness(1) right at the start does not help as that should remove the need to set the compatibility flag, though I wouldn't expect it to scale up the GUI automatically in your program - hence the answer for question 1!

0
votes

The problem is that your application is DPI unaware to make it aware you need to make <dpiaware> tag TRUE in your application's manifest file

still in this situation you can get actual resolution

Here is how you can do it

actualWidth = GetDeviceCaps(hdc, DESKTOPHORZRES);
actualHeight = GetDeviceCaps(hdc, DESKTOPVERTRES);

DESKTOPHORZRES and DESKTOPVERTRES indexes are not mentioned in MSDN but they'll give you actual width and height

there is one function GetDpiForWindow()which give you actual value of DPI but it can be only used in Windows 10 or later