我看到这篇文章,发现没有一个答案完全能够捕捉到我想做的事情。我的笔记本电脑的分辨率是3840x2160,还有两个分辨率为1920x1080的显示器。为了在我的WPF应用程序中获得正确的监视器大小,我必须使应用程序支持DPI
(点每英寸)。然后我使用Win32 API获取了监视器的大小。
我首先将窗口移动到我想要获取大小的监视器上。然后通过获取应用程序MainWindow的hwnd(不一定是主窗口,但我的应用程序只有一个窗口)和指向监视器的IntPtr。接着我创建了MONITORINFOEX结构体的新实例,并调用了GetMonitorInfo方法。
MONITORINFOEX结构体包含屏幕的工作区和完整分辨率,因此您可以返回所需的任何一个。这也将允许您省略对System.Windows.Forms的引用(假设您的应用程序不需要它)。我使用了.NET Framework中的
参考源代码来查找System.Windows.Forms.Screen的解决方案。
public System.Drawing.Size GetMonitorSize()
{
var window = System.Windows.Application.Current.MainWindow;
var hwnd = new WindowInteropHelper(window).EnsureHandle();
var monitor = NativeMethods.MonitorFromWindow(hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST);
NativeMethods.MONITORINFO info = new NativeMethods.MONITORINFO();
NativeMethods.GetMonitorInfo(new HandleRef(null, monitor), info);
return info.rcMonitor.Size;
}
internal static class NativeMethods
{
public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;
[DllImport("user32.dll")]
public static extern IntPtr MonitorFromWindow(IntPtr handle, Int32 flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetMonitorInfo(HandleRef hmonitor, MONITORINFO info);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
public class MONITORINFO
{
internal int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
internal RECT rcMonitor = new RECT();
internal RECT rcWork = new RECT();
internal int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public RECT(System.Drawing.Rectangle r)
{
left = r.Left;
top = r.Top;
right = r.Right;
bottom = r.Bottom;
}
public static RECT FromXYWH(int x, int y, int width, int height) => new RECT(x, y, x + width, y + height);
public System.Drawing.Size Size => new System.Drawing.Size(right - left, bottom - top);
}
}