GetSystemMetrics() returns wrong value for SM_CXSCREEN
我遇到了一个有趣的问题。 至少在Vista中,当桌面DPI设置未设置为100%时,getSystemMetrics(SM_CXSCREEN)返回错误的值。 例如,我在1366x768屏幕中尝试了150%,getSystemMetrics()返回911而不是1366(和1366 / 1.5?911)
根据MSDN,getSystemMetrics(SM_CXSCREEN)返回像素,因此我认为该值不受DPI设置的影响,但确实如此。 那么,有没有更安全的方法来找出真正的,未缩放的屏幕分辨率?
当您超过125%时,程序必须告知操作系统它可以识别DPI。 最好用清单来完成,如MSDN Library这篇文章中所述。
为了使您的应用程序了解dpi的make和manifest文件,并将以下文本放入其中。
1 2 3 4 | <dpiAware>true</dpiAware> </asmv3:windowsSettings> </asmv3:application> </assembly> |
在从诸如GetSystemMetrics或GetClientRect之类的函数获取正确的像素度量之前,您的应用必须向操作系统声明其了解DPI,因此不会搞砸一切。
建议的方式已进行了几处更改。 有关更多详细信息,请参见MSDN文档。
从Windows 10开始:
1 | ::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); |
或从Windows 8.1起:
1 | ::SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); |
或从Vista开始:
1 | ::SetProcessDPIAware(); |
调用此函数后,函数GetSystemMetrics等应将正确的值以像素为单位返回给您的应用。