我有两台显示器:
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;
}
答案 0 :(得分:3)
(1)为每种情况打印系统DPI,以及(2)也尝试SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)可能是有益的。两台显示器的DPI可能不同(或至少Windows认为它们是。)
您告诉Windows,您了解单个系统范围的DPI。为确保应用程序在这种情况下做正确的事情,Windows已经编制了一个虚拟屏幕坐标系统,该系统允许基于主监视器DPI的所有布局的应用程序在两个监视器上获得良好的结果。如果它已使用主监视器的DPI,则在辅助监视器上绘制时,程序可能无法选择最佳图标大小和坐标。同样,如果它使用了辅助监视器的DPI,则应用程序将无法在主要监视器上执行像素完美定位。如果您查看与GDI绘图(ClearType),Direct2D,鼠标和指针消息等的所有交互,则使用双倍较高的DPI然后降尺度可能是一个合理的折衷方案。
如果你的应用程序是每个监视器的DPI意识,我怀疑你会全面获得真正的价值。