Cod*_*ray 5 windows winapi multiple-monitors
我想获得一个监视器句柄(HMONITOR),它可以与Windows多监视器API一起使用,用于通过索引连接到系统的特定监视器.例如,假设我有三台显示器连接到我的系统并构成我桌面的一部分; 我想得到一个监控3的句柄.
我已经知道如何通过调用EnumDisplayDevices函数来获取索引的特定监视器的设备名称.例如:
HMONITOR MonitorFromIndex(int index /* (zero-indexed) */)
{
DISPLAY_DEVICE dd;
dd.cb = sizeof(dd);
if (EnumDisplayDevices(NULL, index, &dd, 0) != FALSE)
{
// We found a match; make sure that it's part of the desktop.
if ((dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
{
// Yup. Now we've got the name of the device:
std::cout << dd.DeviceName << std::endl;
// But how do I obtain an HMONITOR for this device?
// ...
}
}
return NULL; // indicate failure
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们找到了所需设备的名称(dd.DeviceName).我可以使用此名称通过调用以下方法为该监视器创建DC CreateDC:
HDC hDC = CreateDC(dd.DeviceName, dd.DeviceName, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式获取有关该监视器的信息EnumDisplaySettings:
DEVMODE dm;
dm.dmSize = sizeof(dm);
dm.dmDriverExtra = 0;
if (EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm) != FALSE)
{
std::cout << "The monitor supports " << dm.dmBitsPerPel << " bits per pixel." << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这一切都很棒,但我想要一个监视器的句柄.我怎么才能得到它?
我试着调用EnumDisplayMonitors,将句柄传递给我创建的设备上下文CreateDC,希望获得传递给回调函数的监视器的句柄,但没有这样的运气.从未调用回调函数,并EnumDisplayMonitors返回FALSE(不设置错误代码):
struct FoundMatch
{
BOOL found;
HMONITOR hMonitor;
};
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
{
FoundMatch* pfm = reinterpret_cast<FoundMatch*>(dwData);
pfm->found = TRUE;
pfm->hMonitor = hMonitor;
return FALSE; // stop enumerating
}
// elsewhere, after getting the device name and using it to create a DC
FoundMatch fm;
fm.found = FALSE;
fm.hMonitor = NULL;
BOOL result = EnumDisplayMonitors(hDC, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&fm));
Run Code Online (Sandbox Code Playgroud)
很抱歉这么晚的回复,但也许有人会觉得这很有用.
多显示器API至少可以说是极简主义.一旦你得到了你dd.DeviceName,看来你必须去通过EnumDisplayMonitors()枚举,直到找到一个匹配的dd.DeviceName反对MONITORINFOEX.szDevice.
该MONITORINFOEX结构可以通过调用来获得GetMonitorInfo().
这是一个不可编译的C++ 11伪代码:
struct DataBag
{
HMONITOR hmon;
TCHAR* devname;
} bag;
bag.hmon = NULL;
bag.devname = &dd.DeviceName;
BOOL bRes = EnumDisplayMonitors(
NULL, NULL,
[](HMONITOR hMonitor, HDC hDC, LPRECT rc, LPARAM data) -> BOOL {
auto& bag = *reinterpret_cast<DataBag*>(data);
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
if (/* match bag.devname against mi.szDevice */ && GetMonitorInfo(hMonitor, &mi))
{
bag.hmon = hMonitor;
return FALSE;
}
return TRUE;
},
reinterpret_cast<LPARAM>(&bag));
if (bRes && bag.hmon)
{
// Monitor found!
}
Run Code Online (Sandbox Code Playgroud)