windows - 使用 dpiawareness=1 时辅助监视器的坐标很奇怪

标签 windows winapi hdpi

我有两个显示器:

DISPLAY2: 3840x2160 (primary (no idea why it's called DISPLAY2 though)
DISPLAY1: 1920x1080 (located right of primary)

我写了一个小程序来打印他们的几何图形,它输出:

\\.\DISPLAY2; x=0, y=0; 3840x2160
\\.\DISPLAY1; x=3840, y=278; 1920x1080

这看起来是正确的。但是,如果我调用 SetProcessDpiAwareness((PROCESS_DPI_AWARENESS) 1);,它将打印:

\\.\DISPLAY2; x=0, y=0; 7680x4320
\\.\DISPLAY1; x=7680, y=556; 3840x2160

为什么大小刚刚翻了一番?

请注意,我没有在我的显示器上使用任何比例因子,以便能够首先弄清楚发生了什么。但是如果我在主监视器上设置 2 倍缩放比例,它会打印出以下内容:

\\.\DISPLAY2; x=0, y=0; 3840x2160
\\.\DISPLAY1; x=7680, y=556; 3840x2160

为什么辅助监视器从 x=7680 开始?

这是我用来打印值的代码:

#include <Windows.h>
#include <iostream>
#include <ShellScalingAPI.h>

#pragma comment(lib, "Shcore.lib")
#pragma comment(lib, "User32.lib")

BOOL monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM)
{
    MONITORINFOEX info;
    memset(&info, 0, sizeof(MONITORINFOEX));
    info.cbSize = sizeof(MONITORINFOEX);
    if (!GetMonitorInfo(hMonitor, &info))
        return false;

    std::cout << info.szDevice << "; x="<< info.rcMonitor.left << ", y=" << info.rcMonitor.top << "; "
              << (info.rcMonitor.right - info.rcMonitor.left) << "x" << (info.rcMonitor.bottom - info.rcMonitor.top)
              << "\n";

    return true;
}

int main()
{
    int result = SetProcessDpiAwareness((PROCESS_DPI_AWARENESS) 1);
    if (result) {
        std::cout << "Failed to call SetProcessDpiAwareness\n";
        return 1;
    }

    EnumDisplayMonitors(0, 0, monitorEnumCallback, reinterpret_cast<LPARAM>(&result));
    return 0;
}

最佳答案

(1) 为每种情况打印系统 DPI,以及 (2) 也尝试 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) 可能具有指导意义。您的两台显示器的 DPI 可能不同(或者至少 Windows 认为它​​们不同)。

您已告知 Windows 您知道单个系统范围的 DPI。为了确保应用程序在这种情况下做正确的事情,Windows 设计了一个虚拟屏幕坐标系,让应用程序的所有布局都基于主显示器的 DPI,从而在两个显示器上都能获得良好的效果。如果它使用了主监视器的 DPI,您的程序在辅助监视器上绘制时可能不会选择最佳图标大小和坐标。同样,如果它使用了辅助显示器的 DPI,应用程序将无法在主显示器上进行像素完美定位。如果您查看与 GDI 绘图 (ClearType)、Direct2D、鼠标和指针消息等的所有交互,使用双倍更高的 DPI 然后缩小比例可能是一个合理的折衷方案。

如果您的应用程序是每个显示器 DPI 感知的,我怀疑您会全面获得真正的值(value)。

关于windows - 使用 dpiawareness=1 时辅助监视器的坐标很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43003004/

相关文章:

Android:仅针对高 dpi 设备进行优化,但仍支持(小和)中 dpi 屏幕

windows - erlsrv - 无法在 Windows 上创建服务

windows - 如何使用 PowerShell 从 .dll 或 .exe 文件中提取数据

c - 仅使用 Windows API 的 Windows CE 5.0 全屏窗口

c++ - 凭证提供者使用场景 : CPUS_UNLOCK_WORKSTATION removed from Windows 10

android - Android 4 的位图宽度和高度

c# - (C#) graphics.drawImage 有大小限制吗?如何处理?

c++ - 如何从可执行文件的多重/双重代码签名中检索信息

python - 从Python脚本模拟Win+D(显示桌面)