Screens.AllScreens[]
是一个WinForms方法,如果我没记错的话,但是是的,它支持你所有的情况(据我所知)。如果我没记错的话,这个WinForms方法在应用程序启动时初始化静态属性,并且如果屏幕在运行时更改,它不会更新。
由于你正在处理WPF,我建议完全避免使用WinForms。相反,编写自己的Screens
包装器,调用Win32 API。此外,连接一个事件处理程序来通知您显示设置的更改,例如:
Microsoft.Win32.SystemEvents.DisplaySettingsChanged += new EventHandler(this.SystemEvents_DisplaySettingsChanged)
这是我使用的包装器:
这是我使用的包装器:
internal static class Monitors
{
private static List<Monitors.Screen> Screens = null;
internal static List<Monitors.Screen> GetScreens()
{
Monitors.Screens = new List<Monitors.Screen>();
var handler = new NativeMethods.DisplayDevicesMethods.EnumMonitorsDelegate(Monitors.MonitorEnumProc);
NativeMethods.DisplayDevicesMethods.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, handler, IntPtr.Zero);
return Monitors.Screens;
}
private static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, NativeMethods.DisplayDevicesMethods.RECT rect, IntPtr dwData)
{
NativeMethods.DisplayDevicesMethods.MONITORINFO mi = new NativeMethods.DisplayDevicesMethods.MONITORINFO();
if (NativeMethods.DisplayDevicesMethods.GetMonitorInfo(hMonitor, mi))
{
Monitors.Screens.Add(new Monitors.Screen(
(mi.dwFlags & 1) == 1,
mi.rcMonitor.Left,
mi.rcMonitor.Top,
Math.Abs(mi.rcMonitor.Right - mi.rcMonitor.Left),
Math.Abs(mi.rcMonitor.Bottom - mi.rcMonitor.Top)));
}
return true;
}
internal sealed class Screen
{
internal Screen(bool primary, int x, int y, int w, int h)
{
this.IsPrimary = primary;
this.TopX = x;
this.TopY = y;
this.Width = w;
this.Height = h;
}
internal bool IsPrimary { get; private set; }
internal int TopX { get; private set; }
internal int TopY { get; private set; }
internal int Width { get; private set; }
internal int Height { get; private set; }
}
}
internal static class NativeMethods
{
internal static class DisplayDevicesMethods
{
internal delegate bool EnumMonitorsDelegate(IntPtr hMonitor, IntPtr hdcMonitor, NativeMethods.DisplayDevicesMethods.RECT rect, IntPtr dwData);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, EnumMonitorsDelegate lpfnEnum, IntPtr dwData);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetMonitorInfo(IntPtr hmonitor, [In, Out] NativeMethods.DisplayDevicesMethods.MONITORINFO info);
[StructLayout(LayoutKind.Sequential)]
internal struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
internal class MONITORINFO
{
internal int cbSize = Marshal.SizeOf(typeof(NativeMethods.DisplayDevicesMethods.MONITORINFO));
internal NativeMethods.DisplayDevicesMethods.RECT rcMonitor = new NativeMethods.DisplayDevicesMethods.RECT();
internal NativeMethods.DisplayDevicesMethods.RECT rcWork = new NativeMethods.DisplayDevicesMethods.RECT();
internal int dwFlags;
}
}
}
Screen.AllScreens
似乎有一个警告 - 如果屏幕在程序运行时发生更改,并且在您第一次调用它之后,它可能不会报告正确的屏幕。 - James Thorpe