Windows10中多屏顯示器型號獲取並與Screen對應

秦秋随發表於2024-04-19

需求:標識某塊屏,不參與視窗快速移動

@@@code

public class Monitor

{

/// <summary>

/// DeviceID,如: \\.\DISPLAY17

/// </summary>

public String DeviceName { get; set; }

/// <summary>

/// 名稱,如: Default_Monitor

/// </summary>

public String ModelName { get; set; }

/// <summary>

/// 如: MONITOR\Default_Monitor\{4d36e96e-e325-11ce-bfc1-08002be10318}\0004

/// </summary>

public String Description { get; set; }

/// <summary>

/// DeviceString =Microsoft Remote Display Adapter

/// </summary>

public String DeviceString { get; set; }

public String DeviceKey { get; set; }

public int ScreenID { get; set; }

public int ID

{

get

{

if (String.IsNullOrEmpty(DeviceKey))

return 0;

return 1 + int.Parse(DeviceKey.Split('\\').Last());

}

}

public bool Status { get; set; } = true;

public bool IsPrimary { get; set; }

[DllImport("User32.dll")]

private static extern bool EnumDisplayDevices(string lpDevice, int iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, int dwFlags);

[StructLayout(LayoutKind.Sequential)]

public struct DISPLAY_DEVICE

{

public int cb;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]

public string DeviceName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]

public string DeviceString;

public int StateFlags;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]

public string DeviceID;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]

public string DeviceKey;

public DISPLAY_DEVICE(int flags)

{

cb = 0;

StateFlags = flags;

DeviceName = new string((char)32, 32);

DeviceString = new string((char)32, 128);

DeviceID = new string((char)32, 128);

DeviceKey = new string((char)32, 128);

cb = Marshal.SizeOf(this);

}

}

public static List<Monitor> All()

{

DISPLAY_DEVICE lpDisplayDevice = new DISPLAY_DEVICE(0); // OUT

DISPLAY_DEVICE monitor_name = new DISPLAY_DEVICE(0); // OUT

int devNum = 0;

List<Monitor> all = new List<Monitor>();

while (EnumDisplayDevices(null, devNum, ref lpDisplayDevice, 0))

{

if (EnumDisplayDevices(lpDisplayDevice.DeviceName, 0, ref monitor_name, 0))

{

all.Add(new Monitor()

{

DeviceName = lpDisplayDevice.DeviceName.Trim(),

Description = monitor_name.DeviceID,

DeviceString = lpDisplayDevice.DeviceString.Trim(),

ModelName = monitor_name.DeviceID.Split('\\')[1],

DeviceKey = lpDisplayDevice.DeviceKey.Trim()

});

}

++devNum;

}

return all;

}

}

Color[] colors = new Color[] { Color.AliceBlue, Color.LightBlue, Color.LightSeaGreen, Color.LightSkyBlue };

Color getColor(Monitor monitor)

{

return monitor.Status ? (monitor.IsPrimary ? Color.LightGreen : colors[monitor.ScreenID]) : Color.Gray;

}

void renderMonitor()

{

var ss = Properties.Settings.Default.ExcludeScreen.Split(',').ToList();

double p = 0.05;

int w = splitContainer1.Panel2.Width / 2;

int h = splitContainer1.Panel2.Height / 5;

int idx = 0;

foreach (var screen in Screen.AllScreens)

{

var monitor = monitors.FirstOrDefault(r => r.DeviceName == screen.DeviceName);

if (monitor == null)

continue;

if (ss.Count > 0)

{

monitor.Status = !ss.Any(r => r == (idx + 1).ToString());

}

monitor.IsPrimary = screen.Primary;

//int i = int.Parse(screen.DeviceName.Split('Y').Last());

monitor.ScreenID = idx;

var panel = new Label();

panel.AutoSize = false;

panel.TextAlign = ContentAlignment.MiddleCenter;

panel.Text = $"{monitor.ID}\r\n{monitor.ModelName}";

panel.Width = (int)(p * screen.Bounds.Width);

panel.Height = (int)(p * screen.Bounds.Height);

panel.Left = (int)(p * screen.Bounds.Left) + w;

panel.Top = (int)(p * screen.Bounds.Top) + h;

panel.BackColor = getColor(monitor);

panel.Tag = monitor;

panel.DoubleClick += (s, e) =>

{

var m = (s as Label).Tag as Monitor;

if (m != null)

{

m.Status = !m.Status;

(s as Label).BackColor = getColor(m);

Properties.Settings.Default.ExcludeScreen = String.Join(",", monitors.Where(r => !r.Status).Select(r => r.ScreenID + 1).ToList());

Properties.Settings.Default.Save();

}

};

//todo:重新編排序號,按指定序號切屏

idx++;

splitContainer1.Panel2.Controls.Add(panel);

}

}

@@#

相關文章