gpt4 book ai didi

c++ - 将第二个监视器显示设置更改为复制

转载 作者:搜寻专家 更新时间:2023-10-31 01:11:13 24 4
gpt4 key购买 nike

我正在尝试以编程方式使第二台显示器具有重复显示。我下面的功能应该将第二台显示器的显示更改为“重复显示”,即让第二台显示器显示第一台/主显示器上的所有内容。

我的问题: 当我运行我的函数时,它成功地找到了第二个监视器,并且它通过更改 DEVMODE dmPosition 将监视器显示 x 坐标更改为 0,即主监视器屏幕的左侧。 x 属性。我的两个显示器都刷新了自己(它们变黑然后重新显示它们的屏幕)但是第二个显示器仍然有扩展显示而不是重复显示。

有什么想法可以让我的第二台显示器具有重复显示吗?

一些相关信息:
- 我的第二台显示器是液晶电视,通过 HDMI 连接到我的笔记本电脑
- 我的功能代码与此 MSDN Page 上的示例完全相同描述了如何在不重新启动的情况下连接第二台显示器。不过,我已经更改了 LINE 30。
- 我知道我可以使用一个 WinAPI 函数调用更改 Windows 7 上的显示,但我需要我的程序在 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 及更早版本使用与 Vista 及更高版本 (WDDM) 不同的显示驱动程序模型 (XPDM)。 XPDM 上的镜像在很大程度上取决于您的显卡供应商。一般的想法是,为了扩展桌面,你提供一个扩展驱动程序;要镜像桌面的一部分,您需要提供一个镜像驱动程序。

在大多数情况下,每个扩展驱动程序负责显卡上的一个输出。假设您有一张双 DVI 卡,那么您应该在设备管理器中看到两个扩展驱动程序,每个驱动程序负责一个 DVI 端口。当您想要将显示器设置为扩展桌面时,您可以启用扩展驱动程序并为其提供一个合理的位置。

镜像比较棘手。这是不同卡供应商之间的行为可能有所不同的地方。从操作系统的角度来看,这就是正在发生的事情。与显卡端口关联的扩展驱动程序被禁用。如果尚未启用镜像驱动程序,则会启用它。然后将镜像驱动程序放置在 (0, 0)。然后你的显卡/驱动程序内部发生了一些诡计,监视器显示了镜像驱动程序的屏幕缓冲区中的内容。

为了在 XPDM 上将监视器设置为镜像模式,您需要找到它当前正在显示内容的扩展驱动程序并禁用它。这可能就是您要做的全部。一些供应商会自动为您完成剩下的工作,并开始镜像主显示器。有些供应商会执行您的显示器在进入扩展模式之前最后执行的操作。如果您发现您的显示器没有任何显示,您可以尝试启用镜像驱动程序。如果你设法找到镜像驱动程序并启用它,之后会发生什么是任何人的猜测。没有通用的方法将监视器连接到镜像驱动程序。

关于c++ - 将第二个监视器显示设置更改为复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15154542/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com