Jesse Brands
Jesse Brands

Reputation: 2877

EnumDisplayMonitors on specific video/graphics adapter?

I'm looking to enumerate all the displays attached to a specific video adapter. I'm successful in retrieving the video adapter info and creating a HDC from it, but when I call EnumDisplayMonitors on that HDC, nothing happens. EnumDisplayMonitors will work fine if I call it with NULL as the HDC.

win32_root.cpp

for (int i = 0;; ++i) {
    DISPLAY_DEVICE dd = { 0 };
    dd.cb = sizeof(DISPLAY_DEVICE);

    if (!EnumDisplayDevices(NULL, i, &dd, 0)) {
        break;
    }

    if (dd.StateFlags & DISPLAY_DEVICE_ACTIVE) {
        adapters.push_back(new Mage::Adapter(dd));
    }
}

win32_display.cpp

Mage::Adapter::Adapter(DISPLAY_DEVICE dd)
: device(dd)
{
    this->context = CreateDC(L"DISPLAY", device.DeviceName, NULL, NULL);
    EnumDisplayMonitors(this->context, NULL, MonitorEnumProc, (LPARAM)&(this->displays));

Which results in my callback function not being called at all. Changing this->context to NULL will enumerate all displays attached to my computer. Furthermore, this does properly enumerate the displays on the adapter, but I specifically need the display's HMONITOR struct:

if (!EnumDisplayDevices(device.DeviceName, i, &dm, 0)) {
    return;
}

How can I properly enumerate the displays/monitors on a specific DISPLAY_DEVICE?

Upvotes: 1

Views: 884

Answers (1)

riffrazor
riffrazor

Reputation: 467

EnumDisplayDevices is the call you want. You can ask it for adapters, or monitors attached to a specific adapter, etc - but you have to supply the right combination of info to get back a particular set of data.

From the ref link below:

To obtain information on a display monitor, first call EnumDisplayDevices with lpDevice set to NULL. Then call EnumDisplayDevices with lpDevice set to DISPLAY_DEVICE.DeviceName from the first call to EnumDisplayDevices and with iDevNum set to zero. Then DISPLAY_DEVICE.DeviceString is the monitor name.

To query all monitor devices associated with an adapter, call EnumDisplayDevices in a loop with lpDevice set to the adapter name, iDevNum set to start at 0, and iDevNum set to increment until the function fails. Note that DISPLAY_DEVICE.DeviceName changes with each call for monitor information, so you must save the adapter name. The function fails when there are no more monitors for the adapter.

ref: https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-enumdisplaydevicesa

Upvotes: 1

Related Questions