2016-12-21 85 views
0

Windows 7中,多监视器配置。链接信息从SetupDiOpenDevRegKey(EDID)

跨在Linux(openSUSE的13.1)与GCC-MinGW的-5.1.0(这实际上可能是我没有得到预期值的原因)编制。

我得到的所有显示装置的与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
海峡=英特尔(R)HD图形4600
ID = PCI \ VEN_8086 & DEV_0416 & SUBSYS_3 97817AA & REV_06
键= \注册表\机\系统\ CurrentControlSet \控制\视频{BBECD187-6CE4-47FD-915A-A4952B2AC000} \ 0000
初级= Y
- > BPP = 32 W = 1920,H = 1080个FPS = 60

1 - > \ \ DISPLAY2
STR =英特尔(R)HD图形4600
ID = PCI \ VEN_8086 & DEV_0416 & SUBSYS_397817AA & REV_06
键= \注册表\机\ SYSTEM \ CurrentC ontrolSet \控制\视频{BBECD187-6CE4-47FD-915A-A4952B2AC000} \ 0001
初级=正
- > 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... 
    } 
} 

输出(一部分):

...
为实测值EDID '的PnP-监视器(标准)'
关键路径是 '\ REGISTRY \ MACHINE \ SYSTEM \ ControlSet001 \枚举\ DISPLAY \ LGD044F \ 4个& 1BDB7018 UID68092928 \设备参数'

00 FF FF FF FF FF FF 00 26 07 01 00 03 E7 00 00
00 1A 01 03 80 00 00 00 02 00 00 00 00 00 00 00
....

我的问题是,现在,我如何链接这两个信息?我如何将EDID归属于显示器?

预计:

\ \ DISPLAY1 - > EDID1

\。\ DISPLAY2 - > EDID2

  1. 显示#1是LG显示器,显示#2是戴尔(设置为这样,这可以当我改变的显示#2分辨率来验证) ,但戴尔显示器的EDID首先出现,然后出现LG的EDID。 因此,我不能在两个枚举中使用外观顺序,它们不是直接链接的(否则没有问题要问)。

  2. 我也不能依靠消除信息同步速率,因为它可以是相同的所有监视器

  3. 我知道this question and its answer但因为它预计DISPLAY_DEVICE接受的答案并不能帮助我。的DeviceID是在REG关键\ HKLM \系统\ CurrentControlSet \枚举\ DISPLAY和我从EnumDisplayDevices得到\ HKLM \系统\ CurrentControlSet \枚举\ PCI(见 “ID” 行输出)。

  4. 我试图使用标志EDD_GET_DEVICE_INTERFACE_NAME作为 advised in this question,但我没有得到deviceID,如接受的答案中所示。

  5. how to get the key path

我已经检查了list of SetupAPI functions但无法找到如何连接显示信息和SetupDiOpenDevRegKey的结果。

我错过了什么?我错了哪个标志?可以以某种方式使用SetupDiOpenDevRegKey返回的Key路径?

非常感谢。

回答

0

你需要调用两次EnumDisplayDevices功能为每个显示,像这样: Getting the monitor's name with EnumDisplayDevices

lpDevice=NULL第一呼叫和第二个呼叫与lpDevice=DisplayDevice.DeviceName

之后,你在DISPLAY_DEVICE.DeviceID收到预期值。对于我的情况它有下一个值"MONITOR\DVAF001\{4d36e96e-e325-11ce-bfc1-08002be10"