2015-12-04 41 views
3

我使用WPF,意味着该应用程序会显示在不同的视图的许多监视器。WPF:在<code>C#</code></p> <p>我要开始多显示器编程多显示器编程

找遍了互联网上,我已经得到了使用Screen.AllScreens[]的办法,但是我有以下问题

的方法有很多很多显示器连接到PC

案例1:在笔记本电脑: 1台笔记本电脑的屏幕,1个屏幕连接到VGA端口,1个屏幕连接到HDMI端口...

案例2:在桌面:许多屏幕连接到支持多输出

案例3 VGA卡:许多屏幕参数conn等到集线器HDMI或集线器VGA,并集线器连接到PC

我的问题是,Screen.AllScreens[]支持哪种情况?

还有什么其他方式,支持所有的情况?

非常感谢!

+2

应该表现出同样的逻辑屏幕的数量,你已经在您的显示设置中设置,无论它们如何连接。 –

+0

@RonBeyer:谢谢你的回复,你以前试过了吗? – TTGroup

+1

是的,很多时候,即使使用USB监视器。 –

回答

0

Screens.AllScreens[]是一个WinForms方法,如果我没有弄错,但是这是支持你所有的情况(据我所知)。如果我没有记错,那WinForms方法在应用程序启动时初始化静态属性,并且如果在运行时期间更改了屏幕,它将不会更新。

正如你正在处理WPF,我会一起避免WinForms。相反,请编写您自己的Screens包装,它可以调用Win32 API。此外,挂钩事件处理程序时通知您的显示设置更改,例如:

Microsoft.Win32.SystemEvents.DisplaySettingsChanged += new EventHandler(this.SystemEvents_DisplaySettingsChanged); 

这是包装使用:

/// <summary> 
/// This class deals with monitors. 
/// </summary> 
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); // should be sequential 

     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, // 1 = primary monitor 
       mi.rcMonitor.Left, 
       mi.rcMonitor.Top, 
       Math.Abs(mi.rcMonitor.Right - mi.rcMonitor.Left), 
       Math.Abs(mi.rcMonitor.Bottom - mi.rcMonitor.Top))); 
     } 

     return true; 
    } 

    /// <summary> 
    /// Represents a display device on a single system. 
    /// </summary> 
    internal sealed class Screen 
    { 
     /// <summary> 
     /// Initializes a new instance of the Screen class. 
     /// </summary> 
     /// <param name="primary">A value indicating whether the display is the primary screen.</param> 
     /// <param name="x">The display's top corner X value.</param> 
     /// <param name="y">The display's top corner Y value.</param> 
     /// <param name="w">The width of the display.</param> 
     /// <param name="h">The height of the display.</param> 
     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; 
     } 

     /// <summary> 
     /// Gets a value indicating whether the display device is the primary monitor. 
     /// </summary> 
     internal bool IsPrimary { get; private set; } 

     /// <summary> 
     /// Gets the display's top corner X value. 
     /// </summary> 
     internal int TopX { get; private set; } 

     /// <summary> 
     /// Gets the display's top corner Y value. 
     /// </summary> 
     internal int TopY { get; private set; } 

     /// <summary> 
     /// Gets the width of the display. 
     /// </summary> 
     internal int Width { get; private set; } 

     /// <summary> 
     /// Gets the height of the display. 
     /// </summary> 
     internal int Height { get; private set; } 
    } 
} 

internal static class NativeMethods 
{ 
    /// <summary> 
    /// Methods for retrieving display devices. 
    /// </summary> 
    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); 

     /// <summary> 
     /// Retrieves information about a display monitor. 
     /// </summary> 
     /// <param name="hmonitor">A handle to the display monitor of interest.</param> 
     /// <param name="info">A pointer to a MONITORINFO or MONITORINFOEX structure that receives information about the specified display monitor.</param> 
     /// <returns>If the function succeeds, the return value is nonzero.</returns> 
     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     internal static extern bool GetMonitorInfo(IntPtr hmonitor, [In, Out] NativeMethods.DisplayDevicesMethods.MONITORINFO info); 

     /// <summary> 
     /// The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle. 
     /// </summary> 
     [StructLayout(LayoutKind.Sequential)] 
     internal struct RECT 
     { 
      public int Left; 
      public int Top; 
      public int Right; 
      public int Bottom; 
     } 

     /// <summary> 
     /// The MONITORINFO structure contains information about a display monitor. 
     /// </summary> 
     [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; 
     } 
    } 
}