Windows是如何分配显示设备名称(例如\\.\DISPLAY1)并确定显示端口的呢?

8
我们正在编写一个程序,必须能够将设置推送到特定的监视器,因此需要为每个显示设备设置唯一标识符。到目前为止,我能得到的最好结果是查询由EnumDisplayDevices返回的DEVMODE结构的句柄,并查看返回的DISPLAY_DEVICE名称是否包含“DISPLAY1”或“DISPLAY2”(我们只支持最多两个监视器的软件,并且DISPLAY_DEVICE结构的deviceName字段采用\.\DISPLAYx的形式,其中x是自然数,最小为1)。
我的问题是,如果有人从一个终端应用设置到另一个终端,并说:“从我的DISPLAY1和我的DISPLAY2获取所有设置,并将它们应用于另一个终端的DISPLAY1和DISPLAY2”,那么它会将设置应用于连接到相应端口的监视器吗?据我所知,如果只连接了一个监视器,则将分配该监视器的名称为\.\DISPLAY1,如果连接了两个,则通过DVI连接的显示设备为\.\DISPLAY1,通过VGA连接的设备为\.\DISPLAY2。
我已经尝试了逐个拔掉监视器,以不同的顺序重新连接它们,重新启动,仅连接一个再连接第二个等等,似乎总是这样分配它们。我似乎无法让它们分配到相反的名称。如果是这种情况,那么我们应该没问题了。
或者,如果有人知道一种通过MSDN调用程序确定监视器连接到哪个端口(DVI或VGA等)的方法,那将更有帮助。我已经用尽了解决这个问题的各种可能性。
基本上,我想问的是,我的假设关于Windows 7如何分配显示名称是正确的吗?如果不是,那么它是如何完成的?有没有一种改变它的方法?如果有,怎么做?有没有一种确定监视器连接到哪个端口的方法?
顺便说一下,此应用程序使用Qt编写的C++,如果有影响的话。
谢谢。
-Alex aka LeapDayWilliam

1
我觉得很有趣,这个问题没有文档,似乎也没有人知道答案,但是我感谢所有的意见。 - LeapDayWilliam
1个回答

1
我认为你需要的是一些代码来帮助你将显示器的规范名称与其物理位置关联起来。你曾经试图通过查看显示器设备名称来确定这一点,但这并不是一种准确或可靠的方法。根据我的经验,显示器设备名称的编号方案没有任何规律可言。你真正需要的是一种确定哪个显示器位于哪里的方法。
以下是一些非常基本的代码,用于打印出你感兴趣的显示器虚拟像素位置的X、Y坐标。你会注意到,如果你有两个(或更多)显示器,那么这些显示器的X值将根据左侧显示器的宽度增加。你可以根据这些信息计算出一个显示器的物理位置。
    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;
}

我的电脑有两个显示器。我得到了这个输出:

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

这告诉我,句柄为0x00020001的监视器位于第一个监视器的右侧,并且偏移了该监视器的分辨率(1280像素)。

希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接