I am trying to use the EnumDisplayMonitors to create a dynamic array of each monitor and store the DISPLAY_DEVICE structure. Why is the below code not correct?
The callback is called once for each monitor, but your callback is not incrementing through the array each time it is called. You need to do something more like this instead:
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));
Alternatively:
#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));
EnumDisplayMonitors
takes the parameter you pass it and calls your callback once for each monitor, passing it the same parameter every time. Your index into monitorArray
is never incremented. Instead you need to manage the indexing within the callback itself.
Here's a little class that automatically builds a vector of all monitors in the system.
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);
}
};
Use it like this:
MonitorRects monitors;
cout << "You have " << monitors.rcMonitors.size() << " monitors connected.";