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?
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;
};
}
Called using
ScreenArray monitorArray[15];
int i = 0;
EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, reinterpret_cast<LPARAM>(&monitorArray[i++]));
The first in the array (monitorArray[0]
) returns correct information for the second monitor but monitorArray[1]
is max values.
EDIT: Solved The method I used was just implementing a function I created:
MonitorArray *mA = reinterpret_cast<MonitorArray*>(dwData);
mA->addScreen(&iMonitor);
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.";
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With