【问题标题】:EnumDisplayMonitors callbackEnumDisplayMonitors 回调
【发布时间】:2014-10-24 04:28:42
【问题描述】:

我正在尝试使用 EnumDisplayMonitors 创建每个监视器的动态数组并存储 DISPLAY_DEVICE 结构。为什么下面的代码不正确?

BOOL CALLBACK MyInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {

    MONITORINFOEX iMonitor;
    iMonitor.cbSize = sizeof(MONITORINFOEX);
    GetMonitorInfo(hMonitor, &iMonitor);

    if (iMonitor.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER)
    {
        return true;
    }
    else
    {
        *reinterpret_cast<ScreenArray*>(dwData) = ScreenArray(&iMonitor);
        return true;
    };

}

调用使用

ScreenArray monitorArray[15];

int i = 0;
EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, reinterpret_cast<LPARAM>(&monitorArray[i++]));

数组中的第一个 (monitorArray[0]) 返回第二个监视器的正确信息,但 monitorArray[1] 是最大值。

编辑:已解决 我使用的方法只是实现了我创建的一个函数:

MonitorArray *mA = reinterpret_cast<MonitorArray*>(dwData);
        mA->addScreen(&iMonitor);

【问题讨论】:

  • EnumDisplayMonitors 多次调用MyInfoEnumProc,每次在dwData 中传递&amp;monitorArray[0]。数组的其他元素从未被触及。

标签: c++ windows winapi callback


【解决方案1】:

EnumDisplayMonitors 获取您传递给它的参数,并为每个监视器调用一次回调,每次都传递相同的参数。您对monitorArray 的索引永远不会增加。相反,您需要在回调本身内管理索引。

这是一个自动构建系统中所有监视器的向量的小类。

struct MonitorRects
{
    std::vector<RECT>   rcMonitors;

    static BOOL CALLBACK MonitorEnum(HMONITOR hMon,HDC hdc,LPRECT lprcMonitor,LPARAM pData)
    {
        MonitorRects* pThis = reinterpret_cast<MonitorRects*>(pData);
        pThis->rcMonitors.push_back(*lprcMonitor);
        return TRUE;
    }

    MonitorRects()
    {
        EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this);
    }
};

像这样使用它:

MonitorRects monitors;
cout << "You have " << monitors.rcMonitors.size() << " monitors connected.";

【讨论】:

  • 这是一个非常简洁的方法,很好的答案:)
【解决方案2】:

回调会为每个监视器调用一次,但您的回调不会在每次调用时通过数组递增。你需要做更多这样的事情:

struct ScreenArrayInfo
{
    ScreenArray *Array;
    int Count;
    int MaxCount;
};

BOOL CALLBACK MyInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
    MONITORINFOEX iMonitor;
    iMonitor.cbSize = sizeof(MONITORINFOEX);
    GetMonitorInfo(hMonitor, &iMonitor);

    if (iMonitor.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER)
    {
        return true;
    }
    else
    {
        ScreenArrayInfo *info = reinterpret_cast<ScreenArrayInfo*>(dwData);
        if (info->Count == info->MaxCount) return false;
        info->Array[info->Count] = ScreenArray(&iMonitor);
        Info->Count++;
        return true;
    };
}

ScreenArray monitorArray[15];
ScreenArrayInfo info;
info.Array = monitorArray;
info.Count = 0;
info.MaxCount = 15;

EnumDisplayMonitors(NULL, NULL, &MyInfoEnumProc, reinterpret_cast<LPARAM>(&info));

或者:

#include <vector>

BOOL CALLBACK MyInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
    MONITORINFOEX iMonitor;
    iMonitor.cbSize = sizeof(MONITORINFOEX);
    GetMonitorInfo(hMonitor, &iMonitor);

    if (iMonitor.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER)
    {
        return true;
    }
    else
    {
        reinterpret_cast< std::vector<ScreenArray>* >(dwData)->push_back(ScreenArray(&iMonitor));
        return true;
    };
}

std::vector<ScreenArray> monitorArray;
EnumDisplayMonitors(NULL, NULL, &MyInfoEnumProc, reinterpret_cast<LPARAM>(&monitorArray));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-20
    • 2012-09-09
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多