繁体   English   中英

检索辅助监视器的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:

(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);

(结果120,与CreateDC的设备名称无关)

监视器布局
令我严重困惑的另一件事是,第一台显示器位于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.dllGetDpiForMonitor方法。 问题是没有尽早调用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 ,这就是它的不同之处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM