Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetSystemMetrics() returns wrong value for SM_CXSCREEN

I've run into an interesting problem. At least in Vista, getSystemMetrics(SM_CXSCREEN) returns an incorrect value when the desktop DPI settings aren't set at 100%. For example, I tried 150% in a 1366x768 screen and getSystemMetrics() returns 911 instead of 1366 (and 1366 / 1.5 ~ 911)

According to the MSDN, getSystemMetrics(SM_CXSCREEN) returns pixels, so I thought this value wouldn't be affected by the DPI settings - but it is. So is there a safer way to find out the true, unscaled screen resolution?

like image 300
ggambett Avatar asked Apr 13 '10 14:04

ggambett


3 Answers

A program must tell the operating system that it is DPI-aware to get the true resolution when you go past 125%. That's best done with a manifest, as explained in this MSDN Library article.

like image 112
Hans Passant Avatar answered Nov 13 '22 13:11

Hans Passant


To make you application aware of dpi make and manifest file and put the following text in it.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>
like image 38
Asad Khan Avatar answered Nov 13 '22 14:11

Asad Khan


Before getting the correct pixel metrics from functions like GetSystemMetrics, or GetClientRect, your app must declare to the OS that it knows about DPI and therefore won't screw everything up.

There have been several changes to how this is recommended. See the MSDN docs for more details.

From Windows 10 onwards:

::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

Or from Windows 8.1 onwards:

::SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

Or from Vista onwards:

::SetProcessDPIAware();

After calling this, the function GetSystemMetrics etc. should return the correct values to your app in pixels.

like image 30
Toby Sharp Avatar answered Nov 13 '22 13:11

Toby Sharp