首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将PHYSICAL_MONITOR与监视器DeviceID相关联

如何将PHYSICAL_MONITOR与监视器DeviceID相关联
EN

Stack Overflow用户
提问于 2020-07-26 01:25:12
回答 2查看 953关注 0票数 4

我需要帮助将我从"\?\DISPLAY#GSM59AB#5&932a802&1&UID261#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}"),获得的PHYSICAL_MONITOR与监视器DISPLAY_DEVICE.DeviceID相关联(例如,来自与标志EDD_GET_DEVICE_INTERFACE_NAME一起使用的EnumDisplayDevicesEnumDisplayDevices,或者从DISPLAY_DEVICE.DeviceID获得PHYSICAL_MONITOR,反之亦然)。

我需要两者的联系,因为:

  1. HANDLE PHYSICAL_MONITOR.hPhysicalMonitor将用于低水平监测仪,因为我需要向监视器发送命令。
  2. DISPLAY_DEVICE.DeviceID用于从注册表中获取EDID结构(前128个字节对我来说足够了,只需要制造商代码和模型)使用SetupAPI。

1和2被完成,问题是将id与物理监视器相关联。同时,也有可能只使用SetupAPI监视注册表中的EDID,但在这种情况下不可能获得物理监视器句柄。

同一个问题上的MSDN,未解决((

我还注意到一件事:这段代码列举了所有监视器:

代码语言:javascript
运行
复制
DWORD DispNum = 0;
DISPLAY_DEVICE DisplayDevice;
// Initialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);

while ((EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)))
{
    std::wstring deviceName = DisplayDevice.DeviceName;
    DISPLAY_DEVICE DisplayDeviceM;
    ZeroMemory(&DisplayDeviceM, sizeof(DisplayDeviceM));
    DisplayDeviceM.cb = sizeof(DisplayDeviceM);
    int monitorIndex = 0;
    while (EnumDisplayDevices(deviceName.c_str(), monitorIndex, &DisplayDeviceM, EDD_GET_DEVICE_INTERFACE_NAME))
    {
        std::wstring monitorID = DisplayDeviceM.DeviceID;
        ++monitorIndex;
    }
    DispNum++;
}

按与这个相同的顺序:

代码语言:javascript
运行
复制
BOOL CALLBACK EnumProc2(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
LPPHYSICAL_MONITOR pMons = NULL;
DWORD i, mcnt;

MONITORINFOEX mi;
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);

GetMonitorInfo(hMonitor, &mi);

DISPLAY_DEVICE dd;
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
EnumDisplayDevices(mi.szDevice, 0, &dd, EDD_GET_DEVICE_INTERFACE_NAME);

monitorModelMnufac MdlManuf = findMonitorModelManufactFromEDID(dd.DeviceID);

if (!GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &mcnt)) return TRUE;
pMons = (LPPHYSICAL_MONITOR)malloc(mcnt * sizeof(PHYSICAL_MONITOR));
if (GetPhysicalMonitorsFromHMONITOR(hMonitor, mcnt, pMons))
    for (i = 0; i < mcnt; i++)
    {
        AddToMonHandles(pMons[i].hPhysicalMonitor, MdlManuf);
    }
free(pMons);
return TRUE;
}

物理监视器句柄是0,1,2等等,所以我可以使用"monitorIndex“来制作句柄,但我不确定这样做是否安全。

我还在注册表中查找物理监视器句柄,但什么也找不到。

还找到了一些有用的VideoPortDDCMonitorHelper函数,但正如我在googled中所搜索的那样,它需要在驱动程序/过滤器中使用,不能从简单的可执行文件中使用。

同时,所有的调用似乎都是从WIN32U.dll发出的,Ghidra不想解压缩它,或者我只是个新手。

请帮帮我,各位:)

EN

回答 2

Stack Overflow用户

发布于 2020-09-06 14:38:42

为了某种类似的目的,我寻找了EnumDisplayDevicesGetPhysicalMonitorsFromHMONITOR之间的连接;我需要每个监视器的唯一ID,以及设置VCP值的能力。

有些相关员额不给我信心,有一个简单的答案。

我不确定这是否有帮助,但我发现ControlMyMonitor是有用的。

跑步:

代码语言:javascript
运行
复制
controlmymonitor.exe /smonitors

为每个监视器生成信息:

代码语言:javascript
运行
复制
Monitor Device Name: "\\.\DISPLAY1\Monitor0"
Monitor Name: "VX4380 SERIES"
Serial Number: ""
Adapter Name: "NVIDIA GeForce GTX 760"
Monitor ID: "MONITOR\VSC5B34\{4d36e96e-e325-11ce-bfc1-08002be10318}\0004"

而且您可以轻松地设置VCP值。例如,告诉监视器更改为HDMI 1:

代码语言:javascript
运行
复制
controlmymonitor.exe /SetValue "\\.\DISPLAY1\Monitor0" 60 17

另外,如果调用EnumDisplayMonitors以获得PHYSICAL_MONITOR.hPhysicalMonitor,则将该句柄传递给CapabilitiesRequestAndCapabilitiesReply,它将生成以下输出:

代码语言:javascript
运行
复制
prot(monitor)
type(LCD)
model(VX4380)
cmds(01 02 03 07 0C E3 F3)
vcp(02 04 05 08 0B 0C 10 12 14(01 08 06 05 04 0B) 16 18 1A 52 60(0F 10 11 12) 62 87 8D(01 02) A5 AC AE B2 B6 C6 C8 CA CC(01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 12 14 16 17 1A 1E 24) D6(01 04 05) DC(00 01 02 03 05 08 1F) DF E0(00 01 02 03 14) EC(01 02 03) F6 F7(42 FF) FA(00 01 02) FB FC FD FE(00 01 02 04) FF)
mswhql(1)
asset_eep(40)
mccs_ver(2.2)

它恰好包含了模型号。

希望上述命令产生的一些信息能帮助您实现目标。

祝好运!

票数 1
EN

Stack Overflow用户

发布于 2020-08-04 10:15:43

我发现了一些有用的信息,希望能对你有所帮助。

代码语言:javascript
运行
复制
...
while ((EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)))
    {
        std::wstring deviceName = DisplayDevice.DeviceName;
        DISPLAY_DEVICE DisplayDeviceM;
        ZeroMemory(&DisplayDeviceM, sizeof(DisplayDeviceM));
        DisplayDeviceM.cb = sizeof(DisplayDeviceM);
        int monitorIndex = 0;
        while (EnumDisplayDevices(deviceName.c_str(), monitorIndex, &DisplayDeviceM, EDD_GET_DEVICE_INTERFACE_NAME))
        {
            wcout << "deviceName:" << deviceName << endl;
            std::wstring monitorID = DisplayDeviceM.DeviceID;
            wcout <<"monitorID :"<< monitorID<< endl;
            ++monitorIndex;            
        }
        DispNum++;
    }
...

输出:

代码语言:javascript
运行
复制
deviceName: \\.\DISPLAY1

然后使用EnumDisplayMonitors获取HMONITOR,并将其用作GetMonitorInfo的参数。

代码语言:javascript
运行
复制
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
{
    cout << "hmonitor:" << hMon << endl;

    MONITORINFOEX mi;
    mi.cbSize = sizeof(mi);

    GetMonitorInfo(hMon, (LPMONITORINFO)&mi);

    wcout << "deviceName: "<<mi.szDevice << endl;

    DWORD cPhysicalMonitors;
    BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(hMon, &cPhysicalMonitors);
    cout << "GetNumber: " << bSuccess << ", number of physical monitors: " << cPhysicalMonitors << endl;

    LPPHYSICAL_MONITOR pPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc(cPhysicalMonitors * sizeof(PHYSICAL_MONITOR));
    bSuccess = GetPhysicalMonitorsFromHMONITOR(hMon, cPhysicalMonitors, pPhysicalMonitors);
    cout << "GetPhysicalMonitor: " << bSuccess << endl
        << "Handle: " << pPhysicalMonitors->hPhysicalMonitor << endl
        << "Description: ";
    wcout << (WCHAR*)(pPhysicalMonitors->szPhysicalMonitorDescription) << endl;;

    D(pPhysicalMonitors->hPhysicalMonitor);

    DestroyPhysicalMonitors(cPhysicalMonitors, pPhysicalMonitors);
    free(pPhysicalMonitors);

    cout << "---------------------------------------" << endl;

    return TRUE;
}

...

EnumDisplayMonitors(0, 0, MonitorEnum, NULL);

输出:

代码语言:javascript
运行
复制
deviceName: \\.\DISPLAY1

如果这两个输出是相同的,则它们对应于同一个监视器。最后,利用得到的HMONITOR作为GetPhysicalMonitorsFromHMONITOR的参数,得到所需的hPhysicalMonitor

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63095216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档