GetSystemMetrics () возвращает неверное значение для SM CXSCREEN

Я столкнулся с интересной проблемой. По крайней мере, в Vista getSystemMetrics(SM_CXSCREEN) возвращает неверное значение, когда параметры DPI рабочего стола не установлены на 100%. Например, я попробовал 150% на экране 1366x768, и getSystemMetrics () возвращает 911 вместо 1366 (и 1366 / 1.5 ~ 911)

согласно MSDN, getSystemMetrics (SM_CXSCREEN) возвращает пиксели, поэтому я думал, что это значение не будет зависеть от настроек DPI - но это так. Так есть ли более безопасный способ узнать истинное разрешение экрана?

3 ответов


программа должна сообщить операционной системе, что она осознает DPI, чтобы получить истинное разрешение, когда вы проходите мимо 125%. Это лучше всего сделать с манифестом, как объясняется в этом статья библиотеки MSDN.


чтобы вы знали приложение о dpi make и manifest file и поместили в него следующий текст.

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

прежде чем получить правильные пиксельные метрики из таких функций, как GetSystemMetrics или GetClientRect, ваше приложение должно объявить ОС, что оно знает о DPI и поэтому не будет все испортить.

там было несколько изменений в том, как это рекомендуется. Дополнительные сведения см. В документах MSDN.

из Windows 10 и далее:

::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

или из Windows 8.1 и далее:

::SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);

или из Vista и далее:

::SetProcessDPIAware();

после вызывая это, функция GetSystemMetrics и т. д. должны возвращать правильные значения в ваше приложение в пикселях.