2015-10-31 61 views
2

问题
在windows 8.1(和更新版本)上,DPI设置是每个显示器。我可以在系统设置中清楚地看到我的主显示器(笔记本电脑)设置为125%dpi,而我的备用显示器设置为100%dpi。我的应用程序完全是用C#编写的,而我尝试过的每个API调用都会导致辅助监视器的DPI不正确。请记住,那我打电话,我处理的初始化这种方法,并已在我的清单中指定的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设备名称的)

显示器布局
,严重混淆了我,是第一显示器是矩形{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默认是这样做的)。

回答

1

我一直在为此奋斗了一天,在发布问题后不到一个小时,我找到了答案。如果将来有人遇到这个问题,我会在这里留下问题。

正确的方法来获得替代监视器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,这是什么使差异。

相关问题