我正在开发一个WPF / Winforms混合应用程序。我们有一个winforms窗口,用户可以在其中选择此窗口将使用的显示,然后定位和缩放窗口以占用整个显示。
我们遇到了一个关于Windows的奇怪问题。我们使用Screen.AllScreens
来获取屏幕的边界,这些边界用于将窗口捕捉到屏幕。但是,我们发现当不同显示器上的缩放设置不同时,显示器之间会存在实际间隙。
例如,我有一个3监视器系统,其中监视器3设置为100%,监视器1和2设置为125%。系统对话框看起来像这样(没有间隙)。
我们有一个应用程序内可视化,显示Screen.AllScreens返回的内容作为每个监视器的边界,这里看起来像
这是每个显示器的屏幕坐标的打印输出
\\.\DISPLAY1: {X=0,Y=0,Width=2048,Height=1536}
\\.\DISPLAY3: {X=-2400,Y=561,Width=2400,Height=1350}
\\.\DISPLAY2: {X=2560,Y=0,Width=2048,Height=1536}
从数字来看,看起来显示2的x坐标是2560,因为它试图为显示1的2048宽度* 125%= 2560提供空间。但是,似乎这个间隙仅存在于不良坐标中作为跨越跨越此间隙的窗口不会隐藏窗口的一部分。更奇怪的是打印输出显示3的显示尺寸为2400x1350,比实际尺寸1920x1080大125%。
长话短说,我知道Screen.AllScreens是一个winforms调用,也许有点过时了。有没有更好的方法来获取不会受到缩放影响的屏幕坐标,或者我只是坚持警告用户,如果我发现屏幕之间有间隙?
答案 0 :(得分:0)
在调用Application.Run()方法之前,请通知操作系统您的应用程序为dpiAware,如下例所示。这样做会自动将屏幕[]的分辨率结果设置为显示器的原始分辨率,而不是缩放数字。
但是,用户仍然可以将屏幕设置为间隙偏移。我有几台显示器,其中一台是故意离开我的。
static class Program
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
static void Main(string[] args)
{
if (Environment.OSVersion.Version.Major >= 6)
SetProcessDPIAware();
Application.Run(new UIMonitor());
}
}
注意:在Visual Studio中运行时,会自动使用dpiAware,然后当应用程序在Visual Studio外部运行时,它不会,除非您使用SetProcessDPIAware()方法。