EnumDisplayDevices iDevNum not finding main monitor/secondary monitor

Jeff Ibey 41 Reputation points
2021-06-15T19:23:50.22+00:00

I am trying to draw on any monitor not the main monitor. I use the DISPLAY_DEVICE pointer and run through all 10 ports. I check
if (EnumDisplayDevices(0, [0-9],&DISPLAY_DEVICE,0)!=NULL)
If this is true, that means I found a connected display. I than check the StateFlags for main monitor by checking the third bit set.
If(!(DISPLAY_DEVICE.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE))

If it's not set and a display, it's not the main monitor.
If it is set and a display, it is the main monitor.

If I have 2 graphics card, on board GPU and Nvidia GPU on PCIe, and 1 monitor in both cards, I cant find a monitor that is a secondary monitor. All I find is both are set as main based on the state flags. Am I missing something does windows have a main for every GPU/Monitor combo?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
1,907 questions
No comments
{count} votes

Accepted answer
  1. Xiaopo Yang - MSFT 5,851 Reputation points Microsoft Employee
    2021-06-24T02:05:12.123+00:00

    Thank for your attached code again!
    And according to EnumDisplayDevices function, It is necessary to clarify Display Adapter and Display Device.
    You can refer to MADN: Getting Information on a Display Monitor sample or The Following Code(Multi-Byte Character Set) From Internet.

    #include <windows.h>  
    #include <stdio.h>  
      
    #pragma comment(lib, "user32.lib")  
      
    void DumpDevice(const DISPLAY_DEVICE& dd, size_t nSpaceCount )  
    {  
        printf("%*sDevice Name: %s\n", nSpaceCount, "", dd.DeviceName );  
        printf("%*sDevice String: %s\n", nSpaceCount, "", dd.DeviceString );  
        printf("%*sState Flags: %x\n", nSpaceCount, "", dd.StateFlags );  
        printf("%*sDeviceID: %s\n", nSpaceCount, "", dd.DeviceID );  
        printf("%*sDeviceKey: ...%s\n\n", nSpaceCount, "", dd.DeviceKey+42 );  
    }  
      
    int main()  
    {  
        DISPLAY_DEVICE dd;  
      
        dd.cb = sizeof(DISPLAY_DEVICE);  
      
        DWORD deviceNum = 0;  
        while( EnumDisplayDevices(NULL, deviceNum, &dd, 0) ){  
            DumpDevice( dd, 0 );  
            DISPLAY_DEVICE newdd = {0};  
            newdd.cb = sizeof(DISPLAY_DEVICE);  
            DWORD monitorNum = 0;  
            while ( EnumDisplayDevices(dd.DeviceName, monitorNum, &newdd, 0))  
            {  
                DumpDevice( newdd, 4 );  
                monitorNum++;  
            }  
            puts("");  
            deviceNum++;  
        }  
      
        return 0;  
    }  
    

1 additional answer

Sort by: Most helpful
  1. Song Zhu - MSFT 906 Reputation points
    2021-06-16T07:06:02.433+00:00

    If this is true, that means I found a connected display.

    Not so, according to MSDN:

    lpDevice

    A pointer to the device name. If NULL, function returns information for the display adapter(s) on the machine, based on iDevNum.

    So it provides information about the adapter. And you can refer to the remark in the document:

    To get information on the display adapter, call EnumDisplayDevices with lpDevice set to NULL. For example, DISPLAY_DEVICE.DeviceString contains the adapter name.

    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.

    More reference: EnumDisplayDevices giving two Displays even though I have one


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.