我发现在 WPF 中获取监视器计数的最可靠方法是侦听 WM_DISPLAYCHANGE 以了解 mionitor 何时连接和断开连接,然后使用 EnumDisplayMonitors 获取监视器计数。这是代码。
挂钩到 WndProc 以获取 WM_DISPLAYCHANGE 消息。
public partial class MainWindow : IDisposable
{
...
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_DISPLAYCHANGE)
{
int lparamInt = lParam.ToInt32();
uint width = (uint)(lparamInt & 0xffff);
uint height = (uint)(lparamInt >> 16);
int monCount = ScreenInformation.GetMonitorCount();
int winFormsMonCount = System.Windows.Forms.Screen.AllScreens.Length;
_viewModel.MonitorCountChanged(monCount);
}
return IntPtr.Zero;
}
获取展示次数
public class ScreenInformation
{
[StructLayout(LayoutKind.Sequential)]
private struct ScreenRect
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32")]
private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lpRect, MonitorEnumProc callback, int dwData);
private delegate bool MonitorEnumProc(IntPtr hDesktop, IntPtr hdc, ref ScreenRect pRect, int dwData);
public static int GetMonitorCount()
{
int monCount = 0;
MonitorEnumProc callback = (IntPtr hDesktop, IntPtr hdc, ref ScreenRect prect, int d) => ++monCount > 0;
if (EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, callback, 0))
Console.WriteLine("You have {0} monitors", monCount);
else
Console.WriteLine("An error occured while enumerating monitors");
return monCount;
}
}