Reputation: 1985
I have one of those switch views set up to toggle one monitor between two machines and it seems to be stripping off some of the information from the monitor. The monitor's native resolution is 1920x1080@60hz but Windows refuses to let me set it to anything higher than 25hz interlaced, which looks absolutely terrible. I've tried all the drivers and settings suggested by extensive google searching and still nothing.
As a quick project I tried to see if I could force the monitor to a specific display setting using the ChangeDisplaySettingsEx
winapi function but it looks like windows is still checking to make sure the mode is in the incorrect set of supported modes and returns DISP_CHANGE_BADMODE
.
Here's the full function:
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);
}
I've seen How can I force any display resolution/timing I want? and I'd rather not go down the path of using the ATI SDK (I have an ATI Radeon) if at all possible. Any suggestions? I think it would be pretty neat to solve this one with software.
Upvotes: 4
Views: 3655
Reputation: 1985
So doing a search on SuperUser pointed me in the right direction (thanks Josh). The switchview is not passing the EDID data along properly and Windows Vista/7 is adamant about using the EDID data when available in all cases. There was some info about removing the two EDID pins but I didn't want to go down that path.
Doing some googling led me to http://msdn.microsoft.com/en-us/windows/hardware/gg487330.aspx which has a whitepaper on overriding your EDID. That in turn led me to a forums thread here: http://www.sevenforums.com/tutorials/7947-force-dvi-hdmi-resolutions-refresh-rates.html. Someone there was nice enough to create a tool for easily generating an EDID override .dat file.
From that point I did the following:
Used the phoenix.exe tool to generate a .dat for my main monitor (which is working properly)
Loaded the dat up in moninfo.exe to create a .inf driver file
Used "Have disk" to specify my new .inf file
Brazenly ignored the big red warning that the driver was unsigned (generally not a good thing to do)
Rebooted and switched the resolution to the proper one
Upvotes: 4