Windows 7,多显示器配置。
使用gcc-mingw-5.1.0在linux(opensuse 13.1)上编译交叉(实际上可能是我没有得到预期值的原因)。
我获得了 EnumDisplayDevices 所有显示设备的列表: 代码:
int DispNum = 0;
DISPLAY_DEVICE DisplayDevice;
DEVMODE defaultMode;
// initialize DisplayDevice
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
while (EnumDisplayDevices(NULL, DispNum, &DisplayDevice, EDD_GET_DEVICE_INTERFACE_NAME))
{
ZeroMemory(&defaultMode, sizeof(DEVMODE));
defaultMode.dmSize = sizeof(DEVMODE);
if ((DisplayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE) && (DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) && !(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) {
printf("%d -> %s\n\tstr=%s\n\tid=%s\n\tkey=%s\n\tprimary=%s\n", DispNum,DisplayDevice.DeviceName, DisplayDevice.DeviceString,
DisplayDevice.DeviceID, DisplayDevice.DeviceKey,
(DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) ? "y":"n");
if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &defaultMode) ) {
puts("EnumDisplaySettings failed\n");
} else {
printf(" -> bpp=%d w=%d h=%d fps=%d\n",
(int)defaultMode.dmBitsPerPel, (int)defaultMode.dmPelsWidth,
(int)defaultMode.dmPelsHeight, (int)defaultMode.dmDisplayFrequency);
}
}
// Reinit DisplayDevice just to be extra clean
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
DispNum++;
}
输出(强调我的):
0 - > \。\ DISPLAY1
str =英特尔(R)HD Graphics 4600
id = PCI \ VEN_8086& DEV_0416& SUBSYS_397817AA& REV_06
key = \ Registry \ Machine \ System \ CurrentControlSet \ Control \ Video {BBECD187-6CE4-47FD-915A-A4952B2AC000} \ 0000
primary = y
- > bpp = 32 w = 1920 h = 1080 fps = 60
1 - > \。\ DISPLAY2
str =英特尔(R)HD Graphics 4600
ID = PCI \ VEN_8086&安培; DEV_0416&安培; SUBSYS_397817AA&安培; REV_06
关键= \注册\计算机\系统\ CurrentControlSet \控制\影片{BBECD187-6CE4-47FD-915A-A4952B2AC000} \ 0001
初级= N
- > bpp = 32 w = 1920 h = 1080 fps = 60
现在,使用this article我可以获得每个监视器的EDID:
const GUID GUID_CLASS_MONITOR = {0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18};
HDEVINFO devInfo = NULL;
SP_DEVINFO_DATA devInfoData;
ULONG i = 0;
devInfo = SetupDiGetClassDevsEx(
&GUID_CLASS_MONITOR, //class GUID
NULL,NULL,
DIGCF_PRESENT,
NULL,NULL,NULL);
if (NULL == devInfo)
return -1;
for (i=0;ERROR_NO_MORE_ITEMS != GetLastError();i++) {
memset(&devInfoData,0,sizeof(devInfoData));
devInfoData.cbSize = sizeof(devInfoData);
if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData))
{
// look for EDID with SetupDiOpenDevRegKey + RegEnumValue...
}
}
输出(部分):
...
找到'PnP-Monitor(标准)'的值EDID 键路径为'\ REGISTRY \ MACHINE \ SYSTEM \ ControlSet001 \ Enum \ DISPLAY \ LGD044F \ 4& 1BDB7018& 0& UID68092928 \ Device Parameters'
00 ff ff ff ff ff ff 00 26 07 01 00 e7 03 00 00
00 1a 01 03 80 00 00 00 02 00 00 00 00 00 00 00
....
我现在的问题是,如何链接这两个信息?如何将EDID归属到人机界面?
预期:
\。\ DISPLAY1 - > EDID1
\。\ DISPLAY2 - > EDID2
注释
显示器#1是LG显示器,显示器#2是戴尔(设置如此,当我更改显示器#2的分辨率时可以验证这一点),但戴尔显示器的EDID首先出现,然后是LG的EDID。 因此我不能在两个枚举中使用外观顺序,它们没有直接联系(否则无疑问)。
我也不能依赖于分辨率信息或同步速率,因为它可能对所有显示器都相同
我知道this question and its answer但是接受的答案对我没有帮助,因为它希望 DISPLAY_DEVICE.DeviceID 在reg键 \ HKLM \ System \中CurrentControlSet \ Enum \ DISPLAY 以及我从 EnumDisplayDevices 获得的内容位于 \ HKLM \ System \ CurrentControlSet \ Enum \ PCI 中(请参阅“id”中的“id”行)输出)。
我尝试将标记EDD_GET_DEVICE_INTERFACE_NAME用作 advised in this question,但我没有获得接受答案中显示的deviceID。
我已检查list of SetupAPI functions但无法找到如何连接显示信息和SetupDiOpenDevRegKey的结果。
我错过了什么?哪个国旗我错了?可以以某种方式我使用SetupDiOpenDevRegKey返回的密钥路径?
非常感谢。
答案 0 :(得分:0)
您需要为每个显示调用两次EnumDisplayDevices
函数,如下所示:
Getting the monitor's name with EnumDisplayDevices
首先使用lpDevice=NULL
拨打电话,然后使用lpDevice=DisplayDevice.DeviceName
之后,您在DISPLAY_DEVICE.DeviceID中收到了预期值。对于我的情况,它具有下一个值"MONITOR\DVAF001\{4d36e96e-e325-11ce-bfc1-08002be10"