Как Windows назначает имена устройств отображения? (например, \\. \ DISPLAY1) и определить порты дисплея? - PullRequest
5 голосов
/ 22 марта 2012

Мы пишем программу, которая должна иметь возможность передавать настройки на определенные мониторы, требуя, чтобы у нас были уникальные идентификаторы для каждого устройства отображения. Пока что лучшее, что я могу получить, это запросить дескриптор структуры DEVMODE, возвращаемой EnumDisplayDevices, и посмотреть, содержит ли возвращаемое имя DISPLAY_DEVICE либо «DISPLAY1», либо «DISPLAY2» (мы поддерживаем только два монитора с этим программным обеспечением, и deviceName поле структуры DISPLAY_DEVICE имеет вид \. \ DISPLAYx, где x - натуральное число, минимум 1).

Моя проблема в том, что если кто-то применяет настройки с одного терминала к другому и говорит, по сути, «получить все мои настройки с DISPLAY1 и все мои настройки с моего DISPLAY2 и применить их к DISPLAY1 и DISPLAY2 другого терминала», будет ли это применить настройки к мониторам, подключенным к соответствующим портам? Насколько я могу судить, если подключен только 1 монитор, этому монитору присваивается имя \. \ DISPLAY1, а если подключено два, устройством отображения, подключенным через DVI, является \. \ DISPLAY1, а устройством на VGA является \. \ DISPLAY2.

Я пытался отключать мониторы по одному, переподключать их в разных порядках, перезагружать, перезагружать только с одним подключенным, затем подключать секунду и т. Д. И т. Д., И, кажется, всегда назначает их таким образом. Я не могу заставить его присваивать им противоположные имена. Если это так, то мы должны быть в порядке.

В качестве альтернативы, если кто-нибудь знает способ программно определить, к какому порту подключен монитор (DVI или VGA и т. Д.) С помощью вызовов MSDN, это было бы еще более полезно. Я исчерпал практически все возможные варианты решения этой проблемы.

В сущности, я спрашиваю, правильно ли я понимаю свои предположения о том, как Windows 7 назначает имена дисплеям? Если нет, то как это делается? Есть ли способ изменить это? Если так, то как? Есть ли способ определить порт, к которому подключен монитор?

Кстати, это приложение написано на C ++ с использованием Qt, если это вообще имеет значение.

Спасибо.

-Alex aka LeapDayWilliam

1 Ответ

1 голос
/ 19 мая 2012

Я думаю, что вам нужен код, который поможет вам связать каноническое имя монитора с его физическим местоположением. Вы искали решение, в котором вы могли бы принять такое решение, посмотрев на названия устройств монитора, но это не точный или надежный способ сделать это. Из моего опыта нет никакой рифмы или причины для схемы нумерации имен устройств монитора. Что вам действительно нужно, так это способ определить, какой монитор физически расположен и где.

Вот некоторый очень базовый код для распечатки координат 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 пикселей).

Надеюсь, это поможет.

...