你可以用EnumDisplayMonitors()枚举设备,用EnumDisplayDevices()检查它是否是伪监视器
当您使用 GetMonitorInfo() 遍历显示监视器时,您可以获得带有监视器设备名称的 MONITORINFOEX。
然后使用EnumDisplayDevices(),您可以获得DISPLAY_DEVICE,其中包含StateFlags,如果当前监视器是伪监视器(或者如下面的情况下连接到桌面)
BOOL DispayEnumeratorProc(_In_ HMONITOR hMonitor, _In_ HDC hdcMonitor, _In_ LPRECT lprcMonitor, _In_ LPARAM dwData)
{
TClass* self = (TClass*)dwData;
if (self == nullptr)
return FALSE;
MONITORINFOEX monitorInfo;
::ZeroMemory(&monitorInfo, sizeof(monitorInfo));
monitorInfo.cbSize = sizeof(monitorInfo);
BOOL res = ::GetMonitorInfo(hMonitor, &monitorInfo);
if (res == FALSE)
return TRUE;
DISPLAY_DEVICE displayDevice;
::ZeroMemory(&displayDevice, sizeof(displayDevice));
displayDevice.cb = sizeof(displayDevice);
res = ::EnumDisplayDevices(monitorInfo.szDevice, 0, &displayDevice, 0);
if (res == FALSE)
return TRUE;
if (displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
self->RegisterDisplay(monitorInfo);
return TRUE;
}
void TClass::EnumerateDisplayMonitors()
{
BOOL res = ::EnumDisplayMonitors(NULL, NULL, &DispayEnumeratorProc, (LPARAM)this);
if (res == FALSE)
Print("Failed");
}
您还可以通过遍历EnumDisplayDevices() 对您的显示器进行排序
如果您将NULL 作为第一个参数传递给EnumDisplayDevices(),它将根据第二个参数返回适配器的信息。在这种情况下,您的设备将确定顺序。
您可以将DISPLAY_DEVICE 中的DeviceName 与您之前存储的MONITORINFOEX 中的szDevice 进行比较,以对您的HMONITORs 进行排序
void TClass::SortDisplayMonitors()
{
DISPLAY_DEVICE displayDevice;
::ZeroMemory(&displayDevice, sizeof(displayDevice));
displayDevice.cb = sizeof(displayDevice);
std::map<std::string, DWORD> devices;
for (DWORD iDevNum = 0; ::EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0) != FALSE; ++iDevNum)
devices.insert({displayDevice.DeviceName, iDevNum});
auto compare = [&devices](MONITORINFOEX& l, MONITORINFOEX& r)
{
DWORD il = -1;
DWORD ir = -1;
auto foundL = devices.lower_bound(l.szDevice);
if (foundL != devices.end())
il = foundL->second;
auto foundR = devices.lower_bound(r.szDevice);
if (foundR != devices.end())
ir = foundR->second;
return (il < ir);
};
std::sort(m_monitors.begin(), m_monitors.end(), compare);
}
PS:你可以写
DWORD il = std::numeric_limits::max();
安装的
DWORD il = -1;
但不要忘记在包含 Windows.h 之前定义 NOMINMAX