如何在C#中计算连接到PC的显示器?

时间:2015-06-25 07:25:08

标签: c# wpf screen

我需要检测物理连接到计算机的监视器的数量(以确定屏幕配置是单一,扩展,重复模式)。 System.Windows.Forms.Screen.AllScreens.LengthSystem.Windows.Forms.SystemInformation.MonitorCount都会返回虚拟屏幕(桌面)的数量。

因此,如果有2台监视器连接到PC,我可以使用此值决定重复/扩展模式,但我无法确定是否只有一台物理监视器连接到PC,因此屏幕配置处于单屏模式。

3 个答案:

答案 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;
    }
}