C# 使用C的有效友好监视器名称
我的主要开发机器是一台笔记本电脑,有两个屏幕:一个内部屏幕和一个外部三星显示器C# 使用C的有效友好监视器名称,c#,winapi,display,monitor,names,C#,Winapi,Display,Monitor,Names,我的主要开发机器是一台笔记本电脑,有两个屏幕:一个内部屏幕和一个外部三星显示器 Generic PnP Monitor= 1366x768, Top: 0, Left: 1920 -> secondary display SF350_S24F350FH / S24F352FH / S24F354FH (HDMI)= 1920x1080, Top: 0, Left: 0 -> main display 我的代码是: Dispay.cs using System; us
Generic PnP Monitor= 1366x768, Top: 0, Left: 1920 -> secondary display
SF350_S24F350FH / S24F352FH / S24F354FH (HDMI)= 1920x1080, Top: 0, Left: 0 -> main display
我的代码是:
Dispay.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
internal class Display
{
private Rectangle _bounds;
private DisplayOrientation _orientation;
private Rectangle _workingArea;
private string _name,_deviceId;
private static Display[] _displays;
public Rectangle Bounds
{
get
{
return _bounds;
}
}
public DisplayOrientation Orientation
{
get
{
return _orientation;
}
}
public Rectangle WorkingArea
{
get
{
return _workingArea;
}
}
public string DeviceId
{
get
{
return _deviceId;
}
}
public string Name
{
get
{
return _name;
}
}
public static DisplayImpl[] Displays
{
get
{
if (_displays == null) QueryDisplayDevices();
return _displays;
}
private static void QueryDisplayDevices()
{
List<Display> list = new List<Display>();
WinApi.MonitorEnumDelegate MonitorEnumProc = new WinApi.MonitorEnumDelegate((IntPtr hMonitor, IntPtr hdcMonitor, ref WinApi.RECT lprcMonitor, IntPtr dwData) => {
WinApi.MONITORINFOEX mi = new WinApi.MONITORINFOEX() { Size = Marshal.SizeOf(typeof(WinApi.MONITORINFOEX)) };
if (WinApi.GetMonitorInfo(hMonitor, ref mi))
{
WinApi.DISPLAY_DEVICE device = new WinApi.DISPLAY_DEVICE();
device.Initialize();
if (WinApi.EnumDisplayDevices(mi.DeviceName.ToLPTStr(), 0, ref device, 0))
{
Display display = new Display()
{
_name = device.DeviceString,
_deviceId = mi.DeviceName,
_bounds=new Rectangle(mi.Monitor.Left,mi.Monitor.Top,mi.Monitor.Right-mi.Monitor.Left,mi.Monitor.Bottom-mi.Monitor.Top),
_workingArea = new Rectangle(mi.WorkArea.Left, mi.WorkArea.Top, mi.WorkArea.Right - mi.WorkArea.Left, mi.WorkArea.Bottom - mi.WorkArea.Top),
};
list.Add(display);
}
}
return true;
});
WinApi.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, IntPtr.Zero);
_displays=list.ToArray();
}
}
}
我得到了这些结果:
Display 0:
Name: Generic PnP Monitor
DeviceId: \\\\.\\DISPLAY1
Bounds:
Top: 0
Left: 0
Width: 1920
Height: 1080
Display 1:
Name: SF350_S24F350FH / S24F352FH / S24F354FH (HDMI)
DeviceId: \\\\.\\DISPLAY2
Bounds:
Top: 0
Left: 1920
Width: 1366
Height: 768
根据屏幕分辨率和左上角的值,显示器0应为SF350_S24F350FH/S24F352FH/S24F354FH HDMI,以及为什么与显示器1交换?这取决于将哪个显示器定义为主显示器。每个监视器的位置都无关紧要
如果您愿意,这个库可以很好地完成这项工作:根据 要获取显示器上的信息,请首先调用 lpDevice设置为NULL的EnumDisplayDevices。然后打电话 将lpDevice设置为的EnumDisplayDevices 显示从第一次调用到的\u DEVICE.DeviceName iDevNum设置为零的EnumDisplayDevices和。然后 DISPLAY_DEVICE.DeviceString是监视器名称 样本:
private static void QueryDisplayDevices()
{
DISPLAY_DEVICE device = new DISPLAY_DEVICE();
device.Initialize();
uint DispNum = 0;
while (EnumDisplayDevices(null, DispNum, ref device, 0))
{
DISPLAY_DEVICE dev = new DISPLAY_DEVICE();
dev.Initialize();
if (EnumDisplayDevices(device.DeviceName, 0, ref dev, 0))
{
Console.WriteLine("Device Name:" + dev.DeviceName);
Console.WriteLine("Monitor name:" + dev.DeviceString);
}
DispNum++;
device.Initialize();
}
}
根据@Dmo的线索,我使用
它生成正确的监视器名称和设置对!是的,我想是的。这意味着GetMonitorInfo和EnumDisplayDevices之间存在不一致性。GetMonitorInfo将\\\\.\\DISPLAY1视为1920x1080设备外部显示器,但EnumDisplayDevices将\\\\\.\\DISPLAY1视为通用PnP监视器内部显示器。将使用相同的代码尝试该库,并设置与要测试的相同的显示设置。无法复制,请始终按照正确对应的显示设置中的索引顺序返回。我已将EnumDisplaySettings添加到您的示例中,但它仍然使用通用PnP监视器作为1920x1080设备,而它应该是1366x768设备
Display 0:
Name: Generic PnP Monitor
DeviceId: \\\\.\\DISPLAY1
Bounds:
Top: 0
Left: 0
Width: 1920
Height: 1080
Display 1:
Name: SF350_S24F350FH / S24F352FH / S24F354FH (HDMI)
DeviceId: \\\\.\\DISPLAY2
Bounds:
Top: 0
Left: 1920
Width: 1366
Height: 768
private static void QueryDisplayDevices()
{
DISPLAY_DEVICE device = new DISPLAY_DEVICE();
device.Initialize();
uint DispNum = 0;
while (EnumDisplayDevices(null, DispNum, ref device, 0))
{
DISPLAY_DEVICE dev = new DISPLAY_DEVICE();
dev.Initialize();
if (EnumDisplayDevices(device.DeviceName, 0, ref dev, 0))
{
Console.WriteLine("Device Name:" + dev.DeviceName);
Console.WriteLine("Monitor name:" + dev.DeviceString);
}
DispNum++;
device.Initialize();
}
}
Rectangle rect;
Display display;
foreach (PathInfo pi in PathInfo.GetActivePaths())
{
if (!pi.TargetsInfo[0].DisplayTarget.IsAvailable) continue;
rect=System.Windows.Forms.Screen.GetWorkingArea(new Rectangle(pi.Position, pi.Resolution));
display = new DisplayImpl()
{
_name = string.IsNullOrEmpty(pi.TargetsInfo[0].DisplayTarget.FriendlyName)? "Generic PnP Monitor" : pi.TargetsInfo[0].DisplayTarget.FriendlyName,
_deviceId = pi.DisplaySource.DisplayName,
_devicePath=pi.TargetsInfo[0].DisplayTarget.DevicePath,
_bounds = new Rectangle(pi.Position,pi.Resolution),
_workingArea = rect,
};
list.Add(display);
}