GetSystemMetrics()为SM_CXSCREEN返回错误的值

时间:2010-04-13 14:36:58

标签: winapi dpi screen-resolution

我遇到了一个有趣的问题。至少在Vista中,当桌面DPI设置未设置为100%时,getSystemMetrics(SM_CXSCREEN)返回不正确的值。例如,我在1366x768屏幕中尝试了150%而getSystemMetrics()返回911而不是1366(和1366 / 1.5~911)

根据MSDN,getSystemMetrics(SM_CXSCREEN)返回像素,所以我认为这个值不受DPI设置的影响 - 但确实如此。那么有没有更安全的方法来找出真正的,未缩放的屏幕分辨率?

3 个答案:

答案 0 :(得分:10)

当你超过125%时,程序必须告诉操作系统它具有DPI感知能力才能获得真正的分辨率。最好用清单完成,如MSDN Library article中所述。

答案 1 :(得分:5)

让应用程序知道dpi make和manifest文件,并在其中添加以下文本。

<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>

答案 2 :(得分:1)

在从GetSystemMetrics或GetClientRect等函数中获取正确的像素指标之前,您的应用必须向操作系统声明它知道DPI,因此不会搞砸所有内容。

对此建议的方式进行了一些更改。有关详细信息,请参阅MSDN文档。

从Windows 10开始:

::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

或者从Windows 8.1开始:

::SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

或者从Vista开始:

::SetProcessDPIAware();

调用此函数后,函数GetSystemMetrics等应以像素为单位返回正确的值。