none
How can I retrieve monitor information?

    Question

  • am trying to retrieve the monitor ID's as shown in the Windows display properties (#1, 2... etc), but I can't seem to find a way. I have tried using EnumDisplayMonitors as well as EnumDisplayDevices . They both return something like "\.\DISPLAY1". However, this number doesn't always match the number shown by Windows, especially when 2 video cards are being used to drive 3 or more monitors. Is there an API call I am missing to retrieve this information, or is there a way to get it from the registry or somewhere else? Thanks!

    I have tried these methods:
    Win32: EnumDisplayMonitors , EnumDisplayDevices : Neither of these return monitors that aren't active, and neither one returns the correct IDs.
    WMI: "select * from Win32_DesktopMonitor" doesn't return all the monitors, and there is no ID.
    Registry: I have found the monitors in various locations, none of the places I found have the info I am looking for.

    Any help is much appreciated. :)
    Thursday, April 08, 2010 8:06 PM

All replies

  • Hello

    I used this code to perform the tests:


    #include "stdafx.h"
    #include <windows.h>

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

        GetMonitorInfo(hMonitor, &mi);
        wprintf(L"DisplayDevice: %s\n", mi.szDevice);
       
        return TRUE;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
        printf("\n\n\EnumDisplayDevices\n\n\n");

        DISPLAY_DEVICE dd;
         ZeroMemory(&dd, sizeof(dd));
         dd.cb = sizeof(dd);
         for(int i=0; EnumDisplayDevices(NULL, i, &dd, 0); i++)
         {
             wprintf(L"\n\nDevice %d:", i);
           wprintf(L"\n    DeviceName:   '%s'", dd.DeviceName);
           wprintf(L"\n    DeviceString: '%s'", dd.DeviceString);
           wprintf(L"\n    StateFlags:   %s%s%s%s",
                ((dd.StateFlags &
                  DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) ?
                  L"desktop " : L""),
                 ((dd.StateFlags &
                  DISPLAY_DEVICE_PRIMARY_DEVICE     ) ?
                  L"primary " : L""),
                ((dd.StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE) ?
                  L"vga "     : L""),
                 ((dd.StateFlags &
                  DISPLAY_DEVICE_MULTI_DRIVER       ) ?
                  L"multi "   : L""),
                ((dd.StateFlags &
                  DISPLAY_DEVICE_MIRRORING_DRIVER   ) ?
                  L"mirror "  : L""));


           // Get more info about the device
           DISPLAY_DEVICE dd2;
           ZeroMemory(&dd2, sizeof(dd2));
           dd2.cb = sizeof(dd2);
           EnumDisplayDevices(dd.DeviceName, 0, &dd2, 0);
           wprintf(L"\n    DeviceID: '%s'", dd2.DeviceID);
           wprintf(L"\n    Monitor Name: '%s'", dd2.DeviceString);
         }

         printf("\n\n\nEnumDisplayMonitors\n\n\n");

         EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, 0);


     return 0;
    }

    1. when I have only one montor

    it outputs:

    EnumDisplayDevices

    Device 0:
        DeviceName:   '\\.\DISPLAY1'
        DeviceString: 'Mobile Intel(R) 4 Series Express Chipset Family'
        StateFlags:   desktop primary
        DeviceID: 'MONITOR\SEC4E42\{4d36e96e-e325-11ce-bfc1-08002be10318}\0000'
        Monitor Name: 'Generic PnP Monitor'

    Device 1:
        DeviceName:   '\\.\DISPLAY2'
        DeviceString: 'Mobile Intel(R) 4 Series Express Chipset Family'
        StateFlags:
        DeviceID: ''
        Monitor Name: ''


    <omit some other virtual devices>

    EnumDisplayMonitors

    DisplayDevice: \\.\DISPLAY1

    2. When two monitors are connected to the computer, and only one is enabled, the test application outputs:

    EnumDisplayDevices

    Device 0:
        DeviceName:   '\\.\DISPLAY1'
        DeviceString: 'Mobile Intel(R) 4 Series Express Chipset Family'
        StateFlags:   desktop primary
        DeviceID: 'MONITOR\SEC4E42\{4d36e96e-e325-11ce-bfc1-08002be10318}\0000'
        Monitor Name: 'Generic PnP Monitor'

    Device 1:
        DeviceName:   '\\.\DISPLAY2'
        DeviceString: 'Mobile Intel(R) 4 Series Express Chipset Family'
        StateFlags:
        DeviceID: 'MONITOR\DEL400C\{4d36e96e-e325-11ce-bfc1-08002be10318}\0003'
        Monitor Name: 'Generic PnP Monitor'


    EnumDisplayMonitors

    DisplayDevice: \\.\DISPLAY1

    3. When two monitors are connected to the computer, and both are enabled, I get this output:

    EnumDisplayDevices

    Device 0:
        DeviceName:   '\\.\DISPLAY1'
        DeviceString: 'Mobile Intel(R) 4 Series Express Chipset Family'
        StateFlags:   desktop primary
        DeviceID: 'MONITOR\SEC4E42\{4d36e96e-e325-11ce-bfc1-08002be10318}\0000'
        Monitor Name: 'Generic PnP Monitor'

    Device 1:
        DeviceName:   '\\.\DISPLAY2'
        DeviceString: 'Mobile Intel(R) 4 Series Express Chipset Family'
        StateFlags:   desktop
        DeviceID: 'MONITOR\DEL400C\{4d36e96e-e325-11ce-bfc1-08002be10318}\0003'
        Monitor Name: 'Generic PnP Monitor'


    EnumDisplayMonitors

    DisplayDevice: \\.\DISPLAY1
    DisplayDevice: \\.\DISPLAY2

    As you see from the above test results, StateFlags, DeviceID, and Monitor Name can differentiate the conditions. You can get your requested info based on these differences.


    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, April 12, 2010 2:45 AM
  • What I need is the monitor number as shown in the "Screen Resolution" window in Windows 7. These methods work for Windows Vista and earlier, but they don't return the correct order in Windows 7. I was under the impression that MS superceded these functions with the QueryDisplayConfig and related functions for Windows 7?
    Wednesday, April 14, 2010 12:09 AM
  • Hello Jon

    I discussed this with the Shell team. Here is the team's response:

    There is not a supported way to figour out the IDs that you referred to programmatically. It was never a design goal to provide a way for applications to label monitors with the same IDs that the screen resolution control panel uses. What is your application trying to accomplish?


    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, April 23, 2010 2:30 AM
  • I have an application that allows users to move windows between monitors. I need a way to reference a monitor, like "Monitor #1". If Windows is exposing a monitor number via the display properties, it's a bit odd that there isn't a way for other applications to retrieve that number. How else can application developers identify monitors and maintain consistency between applications?
    Friday, April 23, 2010 2:05 PM
  • Hello Jon

    You can move windows between monitors with Windows+Shift+Left or Right. You may also consider labeling monitors according to their position, intead of using the control panel's labeling.


    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, April 26, 2010 5:19 AM
  • To Jialiang Ge,

     

    With all due respect, I find the answers given to the OP by your team a cop-out and frankly nonsensical.  If indeed your statement:

     

    "It was never a design goal to provide a way for applications to label monitors with the same IDs that the screen resolution control panel uses"

     

    ...is true, then could you please explain what the szDevice member of the MONITORINFOEX structure is useful for?  I too am experiencing a significant issue with windows 7 that was not a problem in Vista or XP.  The issue is that when enumerating display monitors, and in turn calling getMonitorInfo, *sometimes* the szDevice returned matches the 'screen resolution' monitor numbers and sometimes it does not.  This is in fact the same issue that the OP is having.

     

    I find your questioning of the validity of what the OP is trying to accomplish a diversion to the fundamental problem reported by the OP.  It is completely reasonable to expect there to be a way to programmatically associate enumerated displays (and display names) with the screen numbers displayed in 'screen resolution'.  Keep in mind that this was not previously a problem in Vista or XP, and to be proactive, I will detail my situation as to why it is important to be able to programmatically determine which monitors are associated with the monitor numbers as displayed on the 'screen resolution' Windows 7 screen.

     

    My application displays multi-monitor presentations where users typically use 2, 3, or 4 monitors.  These monitors are connected to the computer via any combination of the following: VGA, DVI, HDMI, S-Video.  Users set their resolutions based upon their needs as well as the particular display device they have connected to their video card outputs.  Since my application allows for different output screens to the multiple outputs, it is imperative that my application allow the user to associate what output should be displayed to what display monitor number. Without a reliable way to allow the user to match up their desired output screen to their desired monitor number, significant functionality of my application has been lost on Windows 7.  Please also note that this is not simply a matter of "dragging windows" to each of the monitors.  My application displays outputs and bitmaps fullscreen, so "dragging or snapping windows" (by the user) is a non-option for me.

     

    Since Windows 7 does not (as in previous windows OS's) correctly output the szDevice (I.E. \\.\Display2), there is no way for my application to allow a user to correctly indicate which output they want displayed on which of their display #'s (or to 'remember' these preferences for them, since szDevice is not reliable).

     

    Keep in mind that sometimes the szDevice is correct, and sometimes it is not!  (I.E. sometimes the szDevice correlates with the display numbers on the 'screen resolution' screen, and sometimes it does not.)

     

    I find it difficult to believe that there is no intention in Windows 7 to return an szDevice that correlates with the display #'s on the 'screen resolution' window.  If this were the case, then the documentation on MONITORINFOEX and getMonitorInfo on msdn.com should indicate that the szDevice member is depreciated.  You and I both know that this is a bug, and that the szDevice member is *supposed* to correlate with the display #'s as displayed on the 'screen resolution' window!

     

    Please take this problem more seriously, as there are abundances of valid reasons as to why an application developer might want to programmatically determine the display number of enumerated displays!

     

    I also have filed a bug report with Microsoft on this very issue that has now gone without response for over 5 weeks. (It is bug ID 545217 filed via connect.microsoft.com)

     

    Thank you for re-looking at this issue.

    • Edited by pjkdeveloper Tuesday, May 04, 2010 8:17 AM font too small
    • Proposed as answer by hustsean Monday, February 18, 2013 10:40 AM
    • Unproposed as answer by hustsean Monday, February 18, 2013 10:40 AM
    Tuesday, May 04, 2010 8:14 AM
  • Hi

    I must agree with pjkdeveloper.

    This issue has caused us some serious trouble on several production systems using 1-6 screens where knowing the screen number is essential.

    Please do look into this subject.

    Assaf

     

    Friday, April 01, 2011 6:23 PM
  • It is also a problem for end user when existing application stops to works and it is almost impossible to contact the author of the application. For compatibility purpose, I think that Windows XP/Vista behavior should be kept and there should be a possibility to customize the order wia the registry.

    By the way, it was working properly on Windows 8 developer preview and then stop to works in Windows 8 consumer preview and release preview (end user test on an existing application).

    For permanent installation on a desktop, it might be possible in some case to physical swap connections and never touch connections or display settings but for a laptop the problem is worst when an application would display the prentation on the laptop monitor and the presenter screen on the projector.

    Would running an application Under a virtual machine give more or less control on which monitor are used and in which order. In that case, does the order always matches or are independant?

    It is important to fully document how it works and to be consistent.

    Saturday, June 02, 2012 12:50 PM
  • Just bumping this thread.
    Not having access to this identifier number is causing serious headaches for our application which deals with multi monitor setups.

    Tuesday, October 30, 2012 4:04 PM
  • Have you looked at the monitor classes in the WMI namespace (as opposed to CLI namespace that you used).
     
     
    EG from a command prompt
     
    wmic /NameSpace:\\root\wmi PATH WmiMonitorID get /format:List
     
     

    --
    .
    --
    "Rob Bairos" wrote in message news:2f42322f-7b70-43d4-b569-70dbc47c29c2...

    Just bumping this thread.
    Not having access to this identifier number is causing serious headaches for our application which deals with multi monitor setups.

    Wednesday, October 31, 2012 7:33 AM
  • Hi:Jon Tackabury

    Have you resolve it?

    Can you tell me.

    Thanks


    Monday, February 18, 2013 10:27 AM