So what I am trying to do is set a screen resolution on the primary display in C# using ChangeDisplaySettings. I have tested this across multiple windows 7 computers that I own, and the result is always the same: any* valid resolution (those that are listed in the “screen resolution” menu upon right-clicking the desktop) will work just fine, except for the largest resolution that can be selected in that menu, which will cause User32.ChangeDisplaySettings to return -2, which is DISP_CHANGE_BADMODE, meaning that the requested display mode was invalid.
*On some of the computers with larger primary displays, I didn’t bother to test every resolution, and just picked some arbitrary smaller ones & the maximum, as there were too many to test on every single one. I feel confident enough in my testing to say that the maximum resolution ALWAYS fails, while smaller resolutions usually/always succeed (I never had any of them fail during my tests anyways).
Documentation on ChangeDisplaySettings: http://msdn.microsoft.com/en-us/library/dd183411%28VS.85%29.aspx
Documentation on the DEVMODE struct it uses: http://msdn.microsoft.com/en-us/library/dd183565%28v=vs.85%29.aspx
So for an example, lets say I’m running on a 1920×1080 display.
I set my resolution manually (or programmatically) to something else, doesn’t matter what it is or how it was changed, and then run the following code:
DEVMODE dm = new DEVMODE();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
if (User32.EnumDisplaySettings(null, User32.ENUM_CURRENT_SETTINGS, ref dm) != 0)
{
dm.dmPelsWidth = 1920;
dm.dmPelsHeight = 1080;
Console.WriteLine("" + User32.ChangeDisplaySettings(ref dm, User32.CDS_UPDATEREGISTRY) + "\n");
}
*Note that this is not actually the code from the program. I just made this simplified version to cut it down to the bare necessities to illustrate the point.
The program would print out:
-2
Which, as mentioned previously, is the value of DISP_CHANGE_BADMODE, and the resolution would fail to change.
Now, if I changed the values of 1080 and 1920 to 900 and 1600 respectively, another supported resolution on this monitor, and then set the resolution to something other than 1600×900, and then ran this program, it would in fact change the resolution to 1600×900, and return DISP_CHANGE_SUCCESSFUL.
Note that using other flags, such as CDS_RESET (0x40000000 or 1073741824) in place of CDS_UPDATEREGISTRY also result in the same error.
This is a tutorial I found that helped me get started:
http://www.codeproject.com/Articles/6810/Dynamic-Screen-Resolution
[I removed the hyperlink because of the apparent spam prevention system. Sort of silly given that the first to were msdn.microsoft links, and this is a codeproject one, but, w/e]
Note that in the comments section, it seems there is someone who used the provided source files directly, and is experiencing a similar problem. To quote them:
hello ,
i’m using Resolution.cs on my c# application
and it doesn’t work with high resolutions like ” 1366*768 ” & ” 1280*720 ”
can any one help ???
However, despite how commonly ChangeDisplaySettings seems to be recommended by tutorials, I can’t find any information on resolving this issue (which could very well be operating system specific, but I currently lack any non-Windows 7 computers to test on, and even if I did, it would not solve the issue that it doesn’t work on Windows 7 computers)
As it turns out, the tutorial I was using was making the assumption that nothing would change any of the display mode parameters to something invalid during the time that it was at a lower resolution (Such as increasing the refresh rate, which is capped on the monitor’s side. And since I was using the same two monitors for the testing, and the max resolution had a lower max refresh rate than any of the other resolutions, I would encounter this issue.)
A safer method than what is illustrated in the tutorial is to work with the indexes of the display modes or work only with EnumDisplayModes and never touch the data inside the DEVMODE struct.
The following is an excerpt of an example program I whipped up that changes the resolution to the specified parameters, and then back again.
where the functions used here are as follows: