我有两个显示器:
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/