【问题标题】:EnumDisplayMonitors and EnumDisplaySettings disagreeEnumDisplayMonitors 和 EnumDisplaySettings 不一致
【发布时间】:2017-12-03 16:20:17
【问题描述】:

在我的程序中,我使用自己的用户 MonitorEnumProc 调用 EnumDisplayMonitors。我的回调收到一个RECT (lprcMonitor) 报告监视器的显示大小。在我的回调中,我调用EnumDisplaySettings 以获取其他信息。 lprcMonitor 报告显示为 2560x1440,而 EnumDisplaySettings 返回分辨率为 3840x2160 的 DEVMODE

EnumDisplayMonitors 的调用如下所示:

HDC hDC = GetDC(NULL);
EnumDisplayMonitors(hDC, NULL,
                   MonitorEnumProc,
                   (LPARAM)&myModeList);

我没有提供剪切矩​​形,因此没有提供 NULL 参数,因此 EnumDisplayMonitors 应该报告完整的监视器,而不是它的选定区域。我还提供了桌面的DC,这使得函数报告“显示监视器矩形:”

如果 hdcMonitor 不为 NULL,则此矩形是 hdcMonitor 标识的设备上下文的剪辑区域和 显示监视器矩形。矩形坐标为 设备上下文坐标。

实际分辨率是3840x2160,就是我打电话EnumDisplaySettings时报的:

if (GetMonitorInfo(hMonitor, &info)) {
    DEVMODE mode;

    mode.dmSize = sizeof mode;

    if (!EnumDisplaySettings(info.szDevice,
                             ENUM_CURRENT_SETTINGS, &mode)) {

...

什么会导致这种差异?只有一个显示器,并且在我的程序运行期间它从未设置为 2560x1440 的分辨率。目前我的程序依赖 lprcMonitor 来确定要创建的缓冲区的大小,它应该依赖EnumDisplaySettings 的答案吗?

编辑:答案可能涉及 DPI。当 DPI 设置为 100% 时,问题不会出现。

【问题讨论】:

  • 您是否在清单中声明您的应用程序支持 DPI?
  • @doynax 不——这会导致 EnumDisplayMonitors 报告真实分辨率吗?
  • 拜托,拜托,sizeof()的参数请用括号
  • @NmdMystery:很有可能。由于 Vista Windows DPI 缩放是可选的,因为大量应用程序期望默认设置和硬编码像素大小的兼容性较差。使用的方案是为应用程序伪造较低分辨率的图像并放大结果。这将涉及对显示元素的最终屏幕尺寸撒谎。
  • @Michaël Roy:你有什么特别的理由吗?我看不出在 sizeof 运算符中省略括号有任何明显的危险。

标签: c++ c windows winapi


【解决方案1】:

EnumDisplaySettings 返回显示的真实分辨率。

EnumDisplayMonitors 和类似的函数会受到缩放 - 这意味着如果您的应用程序未声明为“dpi 感知”,则操作系统会在大多数函数中对屏幕大小撒谎,而无需缩放100%。

缩放将确保您的“不支持 dpi”的应用程序窗口在高 dpi 屏幕上不会太小(具有模糊的副作用)。

我最喜欢的关于这个主题的文章在 MSDN 上:Writing DPI-Aware Desktop and Win32 Applications

【讨论】:

  • 这些 API 是否与 Windows 10 相关,或者它们已过时并被其他东西取代?
  • EnumDisplayMonitors, EnumDisplaySettings 在所有最新的 Windows 10 版本上都能正常工作。我不知道有任何更新的 C api 具有相同的目的。
猜你喜欢
  • 2012-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
相关资源
最近更新 更多