加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows – 如何从显示设备名称获取HMONITOR句柄?

发布时间:2020-12-14 01:54:10 所属栏目:Windows 来源:网络整理
导读:我想获得一个监视器句柄(HMONITOR),它可以与 Windows多监视器A??PI一起使用,用于通过索引连接到系统的特定监视器.例如,假设我有三台显示器连接到我的系统并构成我桌面的一部分;我想得到一个监控3的句柄. 我已经知道如何通过调用EnumDisplayDevices函数来索引
我想获得一个监视器句柄(HMONITOR),它可以与 Windows多监视器A??PI一起使用,用于通过索引连接到系统的特定监视器.例如,假设我有三台显示器连接到我的系统并构成我桌面的一部分;我想得到一个监控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
}

在上面的代码中,我们找到了所需设备的名称(dd.DeviceName).我可以使用此名称通过调用CreateDC为该监视器创建DC:

HDC hDC = CreateDC(dd.DeviceName,dd.DeviceName,NULL,NULL);

我可以通过调用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;
}

这一切都很棒,但我想要一个监视器的句柄.我怎么才能得到它?

我试图调用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,MonitorEnumProc,reinterpret_cast<LPARAM>(&fm));

解决方法

很抱歉这么晚的回复,但也许有人会觉得这很有用.

多显示器API至少可以说是极简主义.一旦你获得了dd.DeviceName,你就必须通过EnumDisplayMonitors()枚举,直到找到dd.DeviceName与MONITORINFOEX.szDevice的匹配.

可以通过调用GetMonitorInfo()获得MONITORINFOEX结构.

这是一个不可编译的C 11伪代码:

struct DataBag
{
    HMONITOR hmon;
    TCHAR* devname;
} bag;

bag.hmon = NULL;
bag.devname = &dd.DeviceName;

BOOL bRes = EnumDisplayMonitors(
    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!
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读