Basándose en la respuesta anterior por driis, esto es cómo lo manejé Debo señalar que el siguiente código vive en mi archivo Program.cs.
En primer lugar los enlaces a recursos externos y estructuras de datos:
[DllImport("user32")]
private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lpRect, MonitorEnumProc callback, int dwData);
private delegate bool MonitorEnumProc(IntPtr hDesktop, IntPtr hdc, ref Rect pRect, int dwData);
[StructLayout(LayoutKind.Sequential)]
private struct Rect
{
public int left;
public int top;
public int right;
public int bottom;
}
Ahora crea un objeto simple para contener información del monitor:
public class MonitorInfo
{
public bool IsPrimary = false;
public Rectangle Bounds = new Rectangle();
}
Y un envase para guardar estos objetos:
public static List<MonitorInfo> ActualScreens = new List<MonitorInfo>();
y un método para actualizar el contenedor:
public static void RefreshActualScreens()
{
ActualScreens.Clear();
MonitorEnumProc callback = (IntPtr hDesktop, IntPtr hdc, ref Rect prect, int d) =>
{
ActualScreens.Add(new MonitorInfo()
{
Bounds = new Rectangle()
{
X = prect.left,
Y = prect.top,
Width = prect.right - prect.left,
Height = prect.bottom - prect.top,
},
IsPrimary = (prect.left == 0) && (prect.top == 0),
});
return true;
};
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, callback, 0);
}
Luego, más tarde en un formulario, Si quería detectar que una pantalla se ha añadido o eliminado ...
private const int WM_DISPLAYCHANGE = 0x007e;
protected override void WndProc(ref Message message)
{
base.WndProc(ref message);
if (message.Msg == WM_DISPLAYCHANGE)
{
Program.RefreshActualScreens();
// do something really interesting here
}
}
puede haber algunos errores tipográficos en allí, pero esa es la idea básica. ¡Buena suerte!
¿Has probado System.Windows.Forms.SystemInformation.MonitorCount? Lo uso en una de mis aplicaciones y hasta ahora ha funcionado bien, pero no he experimentado con desconectar/conectar el monitor mientras mi aplicación se está ejecutando. –