我需要检测物理连接到计算机的监视器的数量(以确定屏幕配置是单一,扩展,重复模式)。 System.Windows.Forms.Screen.AllScreens.Length
和System.Windows.Forms.SystemInformation.MonitorCount
都会返回虚拟屏幕(桌面)的数量。
因此,如果有2台监视器连接到PC,我可以使用此值决定重复/扩展模式,但我无法确定是否只有一台物理监视器连接到PC,因此屏幕配置处于单屏模式。
答案 0 :(得分:4)
尝试以下方法:
System.Management.ManagementObjectSearcher monitorObjectSearch = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor");
int Counter = monitorObjectSearch.Get().Count;
在以下问题上找到答案:
WMI Get All Monitors Not Returning All Monitors
<强>更新强>
尝试以下检测到拔下显示器的功能:
private int GetActiveMonitors()
{
int Counter = 0;
System.Management.ManagementObjectSearcher monitorObjectSearch = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor");
foreach (ManagementObject Monitor in monitorObjectSearch.Get())
{
UInt16 Status = 0;
try
{
Status = (UInt16)Monitor["Availability"];
}
catch (Exception ex)
{
//Error handling if you want to
continue;
}
if (Status == 3)
Counter++;
}
return Counter;
}
以下是状态列表:https://msdn.microsoft.com/en-us/library/aa394122%28v=vs.85%29.aspx
也许你需要在其他状态代码上增加计数器。查看链接以获取更多信息。
答案 1 :(得分:1)
根据Xanatos的回答,我创建了一个简单的帮助类来检测屏幕配置:
using System;
using System.Management;
using System.Windows.Forms;
public static class ScreensConfigurationDetector
{
public static ScreensConfiguration GetConfiguration()
{
int physicalMonitors = GetActiveMonitors();
int virtualMonitors = Screen.AllScreens.Length;
if (physicalMonitors == 1)
{
return ScreensConfiguration.Single;
}
return physicalMonitors == virtualMonitors
? ScreensConfiguration.Extended
: ScreensConfiguration.DuplicateOrShowOnlyOne;
}
private static int GetActiveMonitors()
{
int counter = 0;
ManagementObjectSearcher monitorObjectSearch = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor");
foreach (ManagementObject Monitor in monitorObjectSearch.Get())
{
try
{
if ((UInt16)Monitor["Availability"] == 3)
{
counter++;
}
}
catch (Exception)
{
continue;
}
}
return counter;
}
}
public enum ScreensConfiguration
{
Single,
Extended,
DuplicateOrShowOnlyOne
}
答案 2 :(得分:0)
我发现在WPF中获取监视器计数的最可靠方法是监听WM_DISPLAYCHANGE以了解何时连接和断开连接器,然后使用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;
}
}