public Win32Monitor(DisplayDeviceW adapter, DisplayDeviceW?display) { Name = display != null ? display.Value.DeviceString : adapter.DeviceString; AdapterName = adapter.DeviceName; DeviceName = display == null ? "<<Unknown Device>>" : display.Value.DeviceName; Debug.Assert(Name != null); var dm = new DeviceMode(); dm.dmSize = (short)Marshal.SizeOf(dm); User32.EnumDisplaySettingsW(adapter.DeviceName.PadRight(32, '\0'), (int)DisplaySettings.CurrentSettings, ref dm); Win32Platform.CheckError("Enumerating display settings."); Width = dm.dmPelsWidth; Height = dm.dmPelsHeight; IntPtr dc = Gdi32.CreateDCW("DISPLAY", adapter.DeviceName, null, IntPtr.Zero); Debug.Assert(dc != IntPtr.Zero); if (Win32Platform.IsWindows81OrGreater) { WidthPhysical = Gdi32.GetDeviceCaps(dc, DeviceCap.HorizontalSize); HeightPhysical = Gdi32.GetDeviceCaps(dc, DeviceCap.VertSize); } else { WidthPhysical = (int)(dm.dmPelsWidth * 25.4f / Gdi32.GetDeviceCaps(dc, DeviceCap.LogPixelsX)); HeightPhysical = (int)(dm.dmPelsHeight * 25.4f / Gdi32.GetDeviceCaps(dc, DeviceCap.LogPixelsY)); } Gdi32.DeleteDC(dc); if ((adapter.StateFlags & DisplayDeviceStateFlags.ModesPruned) != 0) { ModesPruned = true; } var rect = new Rect { Left = dm.dmPosition.X, Top = dm.dmPosition.Y, Right = dm.dmPosition.X + dm.dmPelsWidth, Bottom = dm.dmPosition.Y + dm.dmPelsHeight }; User32.EnumDisplayMonitors(IntPtr.Zero, ref rect, MonitorCallback, null); Win32Platform.CheckError("Creating monitor."); }
internal static extern bool EnumDisplayDevicesW( /* _In_ LPCWSTR */ [In] string lpDevice, /* _In_ DWORD */ [In] uint iDevNum, /* _Inout_ PDISPLAY_DEVICEW */ [In][Out] ref DisplayDeviceW lpDisplayDevice, /* _In_ DWORD */ [In] uint dwFlags );
public static extern bool EnumDisplayDevicesW( [MarshalAs(UnmanagedType.LPWStr)] string lpDevice, uint iDevNum, ref DisplayDeviceW lpDisplayDevice, uint dwFlags );
/// <summary> /// Polls and updates the statuses of connected monitors. /// </summary> private void PollMonitors() { // All monitors are considered inactive until proven otherwise. var inactive = new List <Monitor>(); inactive.AddRange(Monitors); for (uint adapterIndex = 0;; adapterIndex++) { var first = false; var adapter = new DisplayDeviceW(); adapter.Cb = (uint)Marshal.SizeOf(adapter); if (!User32.EnumDisplayDevicesW(null, adapterIndex, ref adapter, 0)) { break; } // If the adapter is inactive - continue; if ((adapter.StateFlags & DisplayDeviceStateFlags.Active) == 0) { continue; } if ((adapter.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != 0) { first = true; } uint displayIndex; for (displayIndex = 0;; displayIndex++) { var display = new DisplayDeviceW(); display.Cb = (uint)Marshal.SizeOf(display); if (!User32.EnumDisplayDevicesW(adapter.DeviceName, displayIndex, ref display, 0)) { break; } // If not active - continue; if ((display.StateFlags & DisplayDeviceStateFlags.Active) == 0) { continue; } // If active - remove from inactive list. // If something was removed, that means this display exists in the monitor array. if (inactive.RemoveAll(x => x.Name == display.DeviceName) > 0) { continue; } UpdateMonitor(new Win32Monitor(adapter, display), true, first); } // HACK: If an active adapter does not have any display devices (as sometimes happens), add it directly as a monitor. if (displayIndex != 0) { continue; } // Remove self from inactive list. if (inactive.RemoveAll(x => x.Name == adapter.DeviceName) > 0) { continue; } UpdateMonitor(new Win32Monitor(adapter, null), true, first); } foreach (Monitor inactiveMonitor in inactive) { UpdateMonitor(inactiveMonitor, false, false); } }