我已经构建了一个WPF应用程序,它有一个可以停靠在桌面边缘的窗口。我使用SHAppBarMessage
WIN32 API来执行对接功能。
在Windows 8.1下,我注意到停靠时,窗口只保留了所需宽度的一半。我的代码从停靠的窗口获取PresentationSource
对象,然后获取TransformToDevice Matrix
对象:
PresentationSource source = PresentationSource.FromVisual( window );
Matrix TransformToDevice = source.CompositionTarget.TransformToDevice;
然后我使用Matrix
将窗口的ActualHeight
和ActualWidth
转换为设备坐标,然后计算桌面上区域的大小以保留窗口:
Size windowSize = (Size) source.CompositionTarget.TransformToDevice.Transform( new Vector( appbarWindow.ActualWidth, appbarWindow.ActualHeight ) );
只要显示器处于100%DPI模式,所有这些代码都有效,但更改DPI设置时问题会出现。在较高的DPI设置(即DPI> 100%)中,为桌面上的窗口保留的区域比窗口窄。
在我的调试中,我在计算上面窗口大小的行上放置了一个断点。我发现在100%DPI设置中,变换Matrix
是Identity矩阵。但是在更改DPI设置后,Matrix
保持不变!
我认为如果DPI设置发生变化,这个变换矩阵会改变吗?如果他们不这样做,我如何获得使DPI设置生效的转换?当DPI设置改变时,我应该调用一种方法吗?如果是这样,我如何获得DPI设置更改的通知?我有引发SystemEvents.DisplaySettingsChanged
事件时调用的代码,并且在DPI设置更改时调用它。但转换始终是Identity Matrix
。他们不应该改变吗?如何获得正确的变换矩阵?
答案 0 :(得分:0)
我发现对我的问题的简短回答是“不”。 Windows 8.1增加了一种称为每监视器DPI感知的新型DPI感知。 WPF代码不是每个监视器DPI感知。事实证明,您必须处理每个监视器的DPI感知,这与WPF内置的系统DPI感知不同。