Я пытаюсь программно заставить 2-й монитор иметь дублированный дисплей. Моя функция, приведенная ниже, должна изменить отображение 2-го монитора на «дублированный дисплей», т.е. заставить 2-й монитор отображать все, что находится на 1-м / основном мониторе.
Моя проблема: Когда я запускаю свою функцию, он успешно находит 2-й монитор и меняет его, отображая координату x дисплея на 0, то есть слева от основного экрана монитора, изменяя свойство DEVMODE dmPosition.x. Оба моих двух монитора обновляются (они становятся черными, а затем снова показывают свой экран), но на втором мониторе все еще есть расширенный дисплей вместо дублированного дисплея.
Любые идеи, как я могу сделать мой второй монитор с дублированием дисплея?
Некоторая важная информация:
— Мой второй монитор ЖК-телевизор и подключен к ноутбуку через HDMI
— Мой код функции точно такой же, как в примере на этом Страница MSDN это описывает, как подключить второй монитор без перезагрузки. Я изменил ЛИНИЯ 30, хотя.
— Я знаю, что могу изменить отображение в Windows 7 с помощью одного вызова функции WinAPI, но мне нужна моя программа для работы в Windows 2000 и выше.
// From http://support.microsoft.com/kb/308216/en-gb Title: You must restart...
BOOL TVManager::AddUnattachedDisplayDeviceToDesktop()
{
DWORD DispNum = 0;
DISPLAY_DEVICE DisplayDevice;
DEVMODE defaultMode;
HDC hdc;
int nWidth;
BOOL bFoundSecondary = FALSE;
hdc = GetDC(0);
nWidth = GetDeviceCaps(hdc, HORZRES);
ReleaseDC(0, hdc);
// Initialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
// Get display devices.
while ((EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)) && (bFoundSecondary == FALSE))
{
ZeroMemory(&defaultMode, sizeof(DEVMODE));
defaultMode.dmSize = sizeof(DEVMODE);
if (!EnumDisplaySettings((LPTSTR)DisplayDevice.DeviceName, ENUM_REGISTRY_SETTINGS, &defaultMode)) {
printf("1\n");
return FALSE; // Store default failed
}
if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
//Found the first secondary device.
_tprintf(_T("Found the first secondary device: Name: %s, Pos: %d, Width: %d\n"), DisplayDevice.DeviceName, defaultMode.dmPosition.x, nWidth);
bFoundSecondary = TRUE;
defaultMode.dmPosition.x = 0; // LINE CHANGED: ONLY CHANGE FROM MSDN'S CODE
defaultMode.dmFields = DM_POSITION;
ChangeDisplaySettingsEx((LPTSTR)DisplayDevice.DeviceName, &defaultMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
_tprintf(_T("Check for error: %u\n"), GetLastError()); // prints "Check for error: 0" which means no error occurred
// A second call to ChangeDisplaySettings updates the monitor.
ChangeDisplaySettings(NULL, 0);
_tprintf(_T("Check for error: %u\n"), GetLastError()); // prints "Check for error: 0" which means no error occurred
}
// Reinitialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
DispNum++;
} // End while the display devices.
return TRUE;
}
В Windows XP и более ранних версиях используется другая модель драйвера дисплея (XPDM), чем в Vista и более поздних версиях (WDDM). Зеркальное отображение на XPDM очень сильно зависит от производителя вашей видеокарты. Общая идея заключается в том, что для расширения рабочего стола вы предоставляете драйвер расширения; для зеркалирования части рабочего стола вы предоставляете драйвер зеркала.
В большинстве случаев каждый драйвер расширения отвечает за один вывод на вашей видеокарте. Допустим, у вас двойная карта DVI, тогда вы должны увидеть два драйвера расширения в вашем диспетчере устройств, каждый из которых отвечает за один из портов DVI. Если вы хотите настроить монитор на расширение рабочего стола, вы активируете драйвер расширения и даете ему разумное расположение.
Зеркальное отображение сложнее. Здесь поведение может немного отличаться у разных поставщиков карт. С точки зрения ОС, это то, что происходит. Драйвер расширения, связанный с портом графической карты, отключен. Зеркальный драйвер включен, если он еще не был включен. Затем зеркальный драйвер помещается в (0, 0). Затем происходит некоторая хитрость внутри вашей видеокарты / драйвера, и монитор показывает, что находится внутри экранного буфера драйвера зеркала.
Чтобы перевести монитор в зеркальный режим в XPDM, вам нужно найти драйвер расширения, с которого он в данный момент показывает данные, и отключить его. Это может быть все, что вам нужно сделать. Некоторые из поставщиков автоматически сделают все остальное за вас и начнут зеркалировать основной дисплей. Некоторые поставщики будут делать то, что ваш монитор делал последним, прежде чем он был переведен в режим расширения. Если на вашем мониторе ничего не отображается, попробуйте включить драйвер зеркала. Если вам удастся найти драйвер зеркала и включить его, то, что произойдет после, можно только догадываться. Универсального способа подключения монитора к драйверу зеркала не существует.
Других решений пока нет …