gpt4 book ai didi

c++ - 是否可以从 Windows 对象管理器路径获取 HMONITOR 句柄?

转载 作者:行者123 更新时间:2023-12-05 02:25:26 25 4
gpt4 key购买 nike

我有一条看起来像这样的路径:

\\?\DISPLAY#IVM1A3E#5&1778d8b3&1&UID260#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}

我想从中得到一个 HMONITOR handle .

使用 WinObj我可以在 GLOBAL 下看到??它是指向某些 \Device\<number> 的符号链接(symbolic link).

我将如何做这样的事情?

编辑:

路径可以分为三部分。首先是\\?\前缀,然后是第二个 DISPLAY#IVM1A3E#5&1778d8b3&1&UID260如果#\ 取代它与 device instance ID 相同.第三{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}GUID for Monitor devices .

通过设备实例 ID,我可以使用 CM_Get_Child 遍历设备树和 CM_Get_Sibling ,使用 CM_Get_Device_ID 检查设备名称.但这只给了我一个 DEVINST不是HMONITOR .

最佳答案

您可以使用 Connecting and configuring displays (CCD) API ,尤其是 The QueryDisplayConfig function它检索有关当前设置中所有显示设备或 View 的所有可能显示路径的信息。

使用以下代码,您将获得设备路径和监视器(及其句柄)之间的对应关系。

#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;
}

在我的 PC(有 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

请注意,您也可以使用 WinRT 的 DisplayManager class 获得相同的信息。 => DisplayView class => Paths property , DisplayPath class , => Target property => TryGetMonitor function

关于c++ - 是否可以从 Windows 对象管理器路径获取 HMONITOR 句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74603194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com