usb*_*102 4 c++ windows winapi
我有一条看起来像这样的路径:
\\?\DISPLAY#IVM1A3E#5&1778d8b3&1&UID260#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
我想从中得到一个HMONITOR
句柄。
使用WinObj我可以在 GLOBAL 下看到?它是指向某些\Device\<number>
.
我该如何去做这样的事情呢?
编辑:
该路径可以分为三部分。首先是\\?\
前缀,然后是第二个DISPLAY#IVM1A3E#5&1778d8b3&1&UID260
(如果#
替换为与设备实例 ID\
相同)。第三是监视器设备的 GUID。{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
通过设备实例 ID,我可以使用CM_Get_Child
和遍历设备树CM_Get_Sibling
,并使用 来检查设备名称CM_Get_Device_ID
。但这只给了我一个DEVINST
而不是一个HMONITOR
。
您可以使用连接和配置显示器 (CCD) API,尤其是QueryDisplayConfig 函数,该函数检索有关当前设置中所有显示设备或视图的所有可能显示路径的信息。
使用以下代码,您将获得设备路径和监视器(及其句柄)之间的对应关系。
#include <Windows.h>
#include <stdio.h>
#include <vector>
#include <tuple>
#include <string>
int main()
{
// get all paths
UINT pathCount;
UINT modeCount;
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount))
return 0;
std::vector<DISPLAYCONFIG_PATH_INFO> paths(pathCount);
std::vector<DISPLAYCONFIG_MODE_INFO> modes(modeCount);
if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths.data(), &modeCount, modes.data(), nullptr))
return 0;
// enum all monitors => (handle, device name)>
std::vector<std::tuple<HMONITOR, std::wstring>> monitors;
EnumDisplayMonitors(nullptr, nullptr, [](HMONITOR hmon, HDC hdc, LPRECT rc, LPARAM lp)
{
MONITORINFOEX mi = {};
mi.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(hmon, &mi);
auto monitors = (std::vector<std::tuple<HMONITOR, std::wstring>>*)lp;
monitors->push_back({ hmon, mi.szDevice });
return TRUE;
}, (LPARAM)&monitors);
// for each path, get GDI device name and compare with monitor device name
for (UINT i = 0; i < pathCount; i++)
{
DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName = {};
deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
deviceName.header.size = sizeof(DISPLAYCONFIG_TARGET_DEVICE_NAME);
deviceName.header.adapterId = paths[i].targetInfo.adapterId;
deviceName.header.id = paths[i].targetInfo.id;
if (DisplayConfigGetDeviceInfo((DISPLAYCONFIG_DEVICE_INFO_HEADER*)&deviceName))
continue;
wprintf(L"Monitor Friendly Name : %s\n", deviceName.monitorFriendlyDeviceName);
wprintf(L"Monitor Device Path : %s\n", deviceName.monitorDevicePath);
DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName = {};
sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
sourceName.header.size = sizeof(DISPLAYCONFIG_SOURCE_DEVICE_NAME);
sourceName.header.adapterId = paths[i].targetInfo.adapterId;
sourceName.header.id = paths[i].sourceInfo.id;
if (DisplayConfigGetDeviceInfo((DISPLAYCONFIG_DEVICE_INFO_HEADER*)&sourceName))
continue;
wprintf(L"GDI Device Name : %s\n", sourceName.viewGdiDeviceName);
// find the monitor with this device name
auto mon = std::find_if(monitors.begin(), monitors.end(), [&sourceName](std::tuple<HMONITOR, std::wstring> t)
{
return !std::get<1>(t).compare(sourceName.viewGdiDeviceName);
});
wprintf(L"Monitor Handle : %p\n", std::get<0>(*mon));
wprintf(L"\n");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在我的电脑(有 2 个显示器)上,它会输出如下内容:
Monitor Friendly Name : C27HG7x
Monitor Device Path : \\?\DISPLAY#SAM0E16#7&307b5912&0&UID1024#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
GDI Device Name : \\.\DISPLAY2
Monitor Handle : 0000000000160045
Monitor Friendly Name : DELL U2715H
Monitor Device Path : \\?\DISPLAY#DELD069#7&307b5912&0&UID1028#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
GDI Device Name : \\.\DISPLAY1
Monitor Handle : 0000000000020083
Run Code Online (Sandbox Code Playgroud)
请注意,您还可以使用 WinRT 的DisplayManager 类=> DisplayView 类=> Paths 属性、DisplayPath 类、=> Target 属性=> TryGetMonitor 函数获取相同的信息
归档时间: |
|
查看次数: |
431 次 |
最近记录: |