【问题标题】:GetSystemMetrics() returns wrong value for SM_CXSCREENGetSystemMetrics() 为 SM_CXSCREEN 返回错误值
【发布时间】:2011-02-07 11:50:07
【问题描述】:

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

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

【问题讨论】:

  • 您从哪种应用程序中调用它?我刚刚尝试从 C 调用该 API,并在 Vista Business 上以不同的 DPI 设置和不同的分辨率运行它,它在每个实例中都正确报告了像素。这是一个 vmware 映像,所以可能会导致差异。
  • 这是一个普通的、普通的 C++ 应用程序。没有标准框架,只有 WinMain。

标签: winapi dpi screen-resolution


【解决方案1】:

当您超过 125% 时,程序必须告诉操作系统它可以识别 DPI,才能获得真正的分辨率。最好使用清单来完成,如MSDN Library article 中所述。

【讨论】:

    【解决方案2】:

    为了让您的应用程序了解 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>
    

    【讨论】:

      【解决方案3】:

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

      已对推荐方式进行了几处更改。有关详细信息,请参阅 MSDN 文档。

      从 Windows 10 开始:

      ::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
      

      或者从 Windows 8.1 开始:

      ::SetProcessDpiAwareness(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
      

      或者从 Vista 开始:

      ::SetProcessDPIAware();
      

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

      【讨论】:

      • 始终建议您使用清单来设置进程的 DPI 感知。有三种类型的 DPI 意识:1)不知道(你认为世界总是 96 DPI)2)系统意识(你理解 DPI,但认为世界总是系统 DPI,永远不会改变)3)每个显示器感知(您了解 DPI 并且它可以在您运行时更改) SetProcessDPIAware() 使您的整个进程系统感知 SetProcessDpiAwareness(...) 让您指定进程的感知模式 SetThreadDpiAwarenessContext(...) 启用子进程DPI 意识
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 2019-02-03
      • 2016-05-13
      • 1970-01-01
      相关资源
      最近更新 更多