检索辅助监视器的 DPI 的正确方法是什么?
What's the correct way to retrieve the DPI of secondary monitors?
问题
在windows 8.1(及更新版本)上,DPI设置为每个监视器。我可以在系统设置中清楚地看到,我的主显示器(笔记本电脑)设置为125%dpi,而我的备用显示器设置为100%dpi。我的应用程序完全用C#编写,我尝试的每个API调用都会导致辅助监视器的DPI不正确。请记住,我在初始化进程时调用此方法,并在我的清单中指定了DPI-aware:
(shcore.dll)
SetProcessDpiAwareness(PROCESS_DPI_AWARENESS::PROCESS_PER_MONITOR_DPI_AWARE);
尝试次数
(shcore.dll)
GetDpiForMonitor(hMonitor, MONITOR_DPI_TYPE::MDT_EFFECTIVE_DPI, &dpiX, &dpiY)
(结果120与hMonitor句柄无关)
(user32.dll)
IntPtr dC = CreateDC(...);
double logX = (double)GetDeviceCaps(dC, LOGPIXELSX);
double logY = (double)GetDeviceCaps(dC, LOGPIXELSY);
(无论CreateDC的设备名称如何,结果120)
监视器布局
另一件让我非常困惑的事情是,第一个显示器位于rect {0,0,1920,1080}
,而第二个显示器位于{2400,0,2400,1350}
,这基本上使实际桌面大小为{4800x1350}
,虚拟桌面大小为{3840x1080}
,但显示器之间缺少像素,我无法解释,也不理解。
Screen 1 Screen 2
Actual Pixels: 1920x1080 2400x1350
Virtual Pixels: 1536x864 1920x1080
Top-Left Coord: 0x0 2400x0
Actual DPI: 120 (125%) 96 (100%)
Returned DPI: 120 (125%) 120 (125%)
我可以确认显示器的DPI不同的另一种方法是,将任何DPI感知应用程序的中心点拖动到显示器之间的边界上,会导致窗口更改大小,使其在显示器之间保持一致(默认情况下,WPF会这样做)。
我已经为此斗争了一天,在我发布问题后不到一个小时,我就找到了答案。如果将来有人遇到这个问题,我将把这个问题留在这里。
获得备用监视器DPI的正确方法是shcore.dll
的GetDpiForMonitor
方法,正如我在上面尝试的那样。问题是SetProcessDpiAwareness
调用得不够早,无法在windows/wpf应用程序中发挥作用。我通过创建一个新控制台应用程序和一个新wpf应用程序并用最少的代码复制它来测试这一点。控制台应用程序返回了正确的值,而wpf应用程序返回的值不正确。
解决方案是将以下内容添加到您的清单文件中:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
</windowsSettings>
</application>
这里的关键是dpiAware标记的值,它是True/PM
,而不仅仅是True
,这就是区别所在。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 通过JNI传递数据数组的最快方法是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 在C++中包含原型文件的正确方法是什么?
- 在 OpenCV C++ 中估计基本矩阵之前对相应点进行归一化的正确方法是什么?
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 将一系列整数放入类的最佳方法是什么?
- 从长整整转换为uint64_t的推荐方法是什么?
- 将此布尔值传递给此函数的最有效方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?