在Windows / C ++中强制显示分辨率

时间:2012-08-07 16:04:52

标签: c++ windows winapi

我设置了一个切换视图,用于在两台机器之间切换一台显示器,它似乎从显示器中剥离了一些信息。显示器的原始分辨率为1920x1080 @ 60hz,但Windows拒绝让我将其设置为高于25hz隔行扫描的任何东西,这看起来非常糟糕。我已经尝试了广泛的谷歌搜索建议的所有驱动程序和设置,但仍然没有。

作为一个快速项目,我试图看看是否可以使用ChangeDisplaySettingsEx winapi函数强制显示器进入特定的显示设置,但看起来窗口仍在检查以确保模式的设置不正确支持的模式并返回DISP_CHANGE_BADMODE

这是完整的功能:

WCHAR deviceName[64];
DISPLAY_DEVICE dd;  
dd.cb = sizeof(DISPLAY_DEVICE);
int index=0;
while (EnumDisplayDevices(NULL, index++, &dd, 0))
{
    // first monitor is the problem one
    if (index == 1) {
        lstrcpy(deviceName, dd.DeviceName);
    }
}

DEVMODE dmScreenSettings;
ZeroMemory(&dmScreenSettings, sizeof(DEVMODE));
dmScreenSettings.dmSize             = sizeof(DEVMODE);
dmScreenSettings.dmPelsWidth        = 1920;
dmScreenSettings.dmPelsHeight       = 1080;
dmScreenSettings.dmBitsPerPel       = 32;
dmScreenSettings.dmDisplayFrequency = 60;
dmScreenSettings.dmFields           = DM_DISPLAYFREQUENCY | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

LONG res = ChangeDisplaySettingsExW((LPCWSTR) &deviceName, &dmScreenSettings, NULL, CDS_RESET, NULL);
if (res != DISP_CHANGE_SUCCESSFUL)
{
    if (res == DISP_CHANGE_BADMODE)
        MessageBoxA(NULL, "Bad mode", "Failed", MB_ICONHAND);
    else if (res == DISP_CHANGE_BADPARAM)
        MessageBoxA(NULL, "Bad Param", "Failed", MB_ICONHAND);
    else
        MessageBoxA(NULL, "Other error", "Failed", MB_ICONHAND);
}

我见过How can I force any display resolution/timing I want?,如果可能的话,我宁愿不去使用ATI SDK(我有ATI Radeon)。有什么建议?我认为用软件解决这个问题非常简洁。

1 个答案:

答案 0 :(得分:4)

因此,在SuperUser上进行搜索时,我指出了正确的方向(感谢Josh)。 switchview没有正确传递EDID数据,Windows Vista / 7在所有情况下都坚持使用EDID数据。有一些关于删除两个EDID引脚的信息,但我不想走那条路。

进行一些谷歌搜索引导我http://msdn.microsoft.com/en-us/windows/hardware/gg487330.aspx,其中有一份覆盖您的EDID的白皮书。这反过来导致我在这里找到论坛帖子:http://www.sevenforums.com/tutorials/7947-force-dvi-hdmi-resolutions-refresh-rates.html。有人可以创建一个轻松生成EDID覆盖.dat文件的工具。

从那时起,我做了以下事情:

  1. 使用phoenix.exe工具为我的主监视器生成.dat(工作正常)

  2. 在moninfo.exe中加载数据以创建.inf驱动程序文件

  3. 使用“Have disk”指定我的新.inf文件

  4. 肆无忌惮地忽略了驱动程序未签名的大红色警告(通常不是一件好事)

  5. 重新启动并将分辨率切换为正确的分辨率