Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does windows assign Display Device names? (eg \\.\DISPLAY1) and determine display ports?

We are writing a program that must be able to push setting to specific monitors, requiring us to have unique identifiers for each display device. So far, the best I can get is querying a handle to the DEVMODE struct returned by EnumDisplayDevices and seeing if the returned DISPLAY_DEVICE name contains either "DISPLAY1" or "DISPLAY2" (we only support up to two monitors with this software, and the deviceName field of the DISPLAY_DEVICE struct is in the form of \.\DISPLAYx where x is a natural number, minimum of 1).

My problem is, if someone applies settings from one terminal to another and says, in effect, "get all my settings from DISPLAY1 and all of my settings from my DISPLAY2 and apply them to another terminal's DISPLAY1 and DISPLAY2," will it apply the settings to the monitors connected to the corresponding ports? As far as I can tell, if there is only 1 monitor connected, that monitor is assigned the name \.\DISPLAY1, and if there are two connected, the display device connected via DVI is \.\DISPLAY1 and the device on VGA is \.\DISPLAY2.

I've tried unplugging the monitors one at a time, reconnecting them in different orders, rebooting, rebooting with only one connected, then connecting a second, etc etc, and it seems to always assign them this way. I can't seem to make it assign them to the opposite names. If this is the case, then we should be OK.

Alternatively, if anyone knows of a way to programmatically determine which port to which a monitor is connected (DVI or VGA etc) using MSDN calls, that would be even more helpful. I've exhausted basically every option I can think of in solving this problem.

Basically, I'm asking, am I correct in my assumptions as to how Windows 7 assigns names to the displays? If not, how is it done? Is there a way to change it? If so, how? Is there a way to determine the port to which a monitor is connected?

By the way, this application is written in C++ utilizing Qt, if that matters at all.

Thank you.

-Alex aka LeapDayWilliam

like image 532
LeapDayWilliam Avatar asked Mar 22 '12 19:03

LeapDayWilliam


1 Answers

I think what you're looking for is some code to help you associate a monitor's canonical name with its physical location. You were looking for a solution where you'd be able to make this determination by looking at the device names of the monitor, but this isn't an accurate or reliable way to do it. From my experience there's no rhyme or reason to the numbering scheme for the monitor device names. What you really need is a way to determine which monitor is physically located where.

Here is some very basic code to print out the X,Y coordinates of the virtual pixel location for the monitor you're interested in. You'll notice that if you have two (or more) monitors the X value of those monitors will increase based on the width of the monitor to the left. You can calculate a monitor's physical location based on this information.

    BOOL CALLBACK enumMonitorCallback(
  __in  HMONITOR hMonitor,
  __in  HDC hdcMonitor,
  __in  LPRECT lprcMonitor,
  __in  LPARAM dwData
)
{
    printf("Monitor: %p (X,Y): (%d,%d) (Width, Height): (%d,%d) \n", hMonitor, lprcMonitor->left, lprcMonitor->top, lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top);
    return TRUE;
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;
    BOOL res = EnumDisplayMonitors(NULL, NULL, enumMonitorCallback, NULL);
    getchar();
    return nRetCode;
}

My machine has two monitors. I get this output:

    Monitor: 0x00C005E1 (X,Y): (0,0) (Width, Height): (1280,1024)
    Monitor: 0x00020001 (X,Y): (1280,0) (Width, Height): (1280,1024)

Which tells me that monitor with handle 0x00020001 is located to the right of the first monitor and is offset by the resolution of that monitor (1280px).

I hope that helps.

like image 139
Tra5is Avatar answered Oct 05 '22 17:10

Tra5is