changing screen resolution(C#)

Divil, I wrote some code. but in some reason, it doesn't make the effect. I added here the code. I'll Appreciate, if you'll take a look.
C#:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices; 

namespace ScreenResolution
{
	
	public class Form1 : System.Windows.Forms.Form
	{
		
		
		
		public enum DMDO
		{
			DEFAULT = 0,
			D90 = 1,
			D180 = 2,
			D270 = 3
		}

		[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
		struct DEVMODE
		{
		
			private const int CCHDEVICENAME = 32;
			private const int CCHFORMNAME = 32;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHDEVICENAME)]
			public string dmDeviceName;
			public short dmSpecVersion;
			public short dmDriverVersion;
			public short dmSize;
			public short dmDriverExtra;
			public int dmFields;

			public int dmPositionX;
			public int dmPositionY;
			public DMDO dmDisplayOrientation;
			public int dmDisplayFixedOutput;

			public short dmColor;
			public short dmDuplex;
			public short dmYResolution;
			public short dmTTOption;
			public short dmCollate;
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHFORMNAME)]
			public string dmFormName;
			public short dmLogPixels;
			public int dmBitsPerPel;
			public int dmPelsWidth;
			public int dmPelsHeight;
			public int dmDisplayFlags;
			public int dmDisplayFrequency;
			public int dmICMMethod;
			public int dmICMIntent;
			public int dmMediaType;
			public int dmDitherType;
			public int dmReserved1;
			public int dmReserved2;
			public int dmPanningWidth;
			public int dmPanningHeight;
		}

		//--------------------------------\

		
		
		[DllImport("user32.dll", CharSet=CharSet.Auto)]
		static extern int ChangeDisplaySettings( DEVMODE lpDevMode,  int dwFlags);
		
		// should I use this line?
		//static extern int ChangeDisplaySettings( [In] ref DEVMODE lpDevMode,  int dwFlags);

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

	
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.Size = new System.Drawing.Size(300,300);
			this.Text = "Form1";
		}
		#endregion

	
	
		static void Main() 
		{
			Form1 r = new Form1();
			r.ChangeRes();
			Application.Run(new Form1());
		}
      
		void ChangeRes()
		{
			
			
			long RetVal=0;
			DEVMODE dm = new DEVMODE();
            dm.dmPelsWidth = 600;
			dm.dmPelsHeight= 800;
			dm.dmFields  = dm.dmPelsWidth | dm.dmPelsHeight;
			
			RetVal = ChangeDisplaySettings(dm, 0);
			
		
		}

	}
}
 
You're right. It doesn't work and even returns 0 meaning success. I even put a couple more parameters in there and it does the same exact thing:
C#:
int RetVal=0;
DEVMODE dm = new DEVMODE();
dm.dmPelsWidth = 800;
dm.dmPelsHeight= 600;
dm.dmBitsPerPel= 24;
dm.dmDisplayFrequency= 100;

dm.dmFields  = dm.dmPelsWidth | dm.dmPelsHeight | dm.dmBitsPerPel | dm.dmDisplayFrequency;

RetVal= ChangeDisplaySettings(dm, 0);
a.MB.ShowDialog(RetVal);
and the really weird part is that the return value is always 0 even when I put 1 in for all the parameters!!!
 
there is one more commands which need to be added:
The reason that it doesn't change is because we need to set the
"dm.dmFields" using the "DM_PELSWIDTH , DM_PELSHEIGHT"
struct members

I don't know how to make this in C#.
this is a VB code
C#:
Const DM_PELSWIDTH = &H80000
Const DM_PELSHEIGHT = &H100000
The above commands don't pass the compiler.

and then

C#:
dm.dmPelsWidth = 600;
dm.dmPelsHeight= 800;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT
ChangeDisplaySettings(dm, 0);
 
still, doesn't work. even when I use the following changes:

C#:
static extern int ChangeDisplaySettings( [In] ref DEVMODE lpDevMode,  int dwFlags);
.
.
.
DEVMODE dm = new DEVMODE();
long RetVal=0;

const int DM_PELSWIDTH = 0x80000;
const int DM_PELSHEIGHT = 0x100000;

dm.dmPelsWidth = 600;
dm.dmPelsHeight= 800;

dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;

RetVal = ChangeDisplaySettings(ref dm, 0);

Still, return 0 and doesn't make the shanges...
 
Here is my code, it does not work either. I read for Xp that you have to call the Enum function and the Enum function works but it is weird!
C#:
public class Api
		{
//------------------------------
			[DllImport("user32.dll", EntryPoint = "SendMessageA")]
			public static extern uint SendMessage(IntPtr hWnd, uint wMsg, uint wParam, uint lParam);
//------------------------------			
			[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
				public struct DevMode
			{
				const int CCHDEVICENAME = 32;
				const int CCHFORMNAME = 32;

				[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHDEVICENAME)]
				public string dmDeviceName;
				public short dmSpecVersion;
				public short dmDriverVersion;
				public short dmSize;
				public short dmDriverExtra;
				public int dmFields;

				public int dmPositionX;
				public int dmPositionY;
				public int dmDisplayFixedOutput;

				public short dmColor;
				public short dmDuplex;
				public short dmYResolution;
				public short dmTTOption;
				public short dmCollate;
				[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHFORMNAME)]
				public string dmFormName;
				public short dmLogPixels;
				public int dmBitsPerPel;
				public int dmPelsWidth;
				public int dmPelsHeight;
				public int dmDisplayFlags;
				public int dmDisplayFrequency;
				public int dmICMMethod;
				public int dmICMIntent;
				public int dmMediaType;
				public int dmDitherType;
				public int dmReserved1;
				public int dmReserved2;
				public int dmPanningWidth;
				public int dmPanningHeight;

				public const int CCDEVICENAME = 32;
				public const int CCFORMNAME = 32;

				public const int DM_BITSPERPEL = 0x40000;
				public const int DM_PELSWIDTH = 0x80000;
				public const int DM_PELSHEIGHT = 0x100000;

				public const int CDS_UPDATEREGISTRY = 0x00000001;
				public const int CDS_TEST = 0x00000002;
				public const int CDS_GLOBAL = 0x00000008;
				public const int CDS_FULLSCREEN = 0x00000004;
				public const int CDS_RESET  = 0x40000000;

				public const int DISP_CHANGE_SUCCESSFUL = 0;
				public const int DISP_CHANGE_RESTART = 1;
				public const int DISP_CHANGE_FAILED = -1;
				public const int DISP_CHANGE_BADMODE = -2;
				public const int DISP_CHANGE_NOTUPDATED = -3;
				public const int DISP_CHANGE_BADFLAGS = -4;
				public const int DISP_CHANGE_BADPARAM = -5;
			}
//------------------------------
			[DllImport("user32.dll", EntryPoint="EnumDisplaySettingsW")]
			static extern int EnumDisplaySettings(string dispDevice, int modeNum, ref DevMode settings);
			public static string GetDisplayModes(bool All)
			{
				int ENUM_CURRENT_SETTINGS = -1;

				DevMode dm=new DevMode();
				dm.dmSize= (short)Marshal.SizeOf(typeof(DevMode));
				dm.dmDriverExtra = 0;
				int ret= -1;
				StringBuilder SB=new StringBuilder(50);

				if(All)
				{
					for(int i=0; ret != 0; i++)
					{
						ret= EnumDisplaySettings(null, i, ref dm);
						SB.Append(i+")"+dm.dmDeviceName+"  "+"BpP: "+dm.dmBitsPerPel+"  W: "+dm.dmPelsWidth+
							"  H: "+dm.dmPelsHeight+"  Fr: "+dm.dmDisplayFrequency+"  Flags: "+dm.dmDisplayFlags+"\n");
					}
				}
				else
				{
					EnumDisplaySettings(null, ENUM_CURRENT_SETTINGS, ref dm);
					SB.Append(dm.dmDeviceName+"  "+"BpP: "+dm.dmBitsPerPel+"  W: "+dm.dmPelsWidth+
						"  H: "+dm.dmPelsHeight+"  Fr: "+dm.dmDisplayFrequency+"  Flags: "+dm.dmDisplayFlags+"\n");
				}
				return SB.ToString();
			}
//------------------------------
			[DllImport("user32.dll", EntryPoint="ChangeDisplaySettingsA")]
			static extern int ChangeDisplaySettings(ref DevMode lpDevMode, int dwFlags);
			public static int ChangeDisplay(int W, int H, int ColorDepth)
			{
				int ret= 0;
				DevMode dm = new DevMode();
				
				EnumDisplaySettings(null, 0, ref dm);

				dm.dmFields  = DevMode.DM_PELSWIDTH | DevMode.DM_PELSHEIGHT | DevMode.DM_BITSPERPEL;
				dm.dmPelsWidth = W;
				dm.dmPelsHeight= H;
				dm.dmBitsPerPel= ColorDepth;
				//dm.dmDisplayFrequency= 100;

				ret= ChangeDisplaySettings(ref dm, 0);//DevMode.CDS_UPDATEREGISTRY);
	a.MB.ShowDialog(ret);
				return ret;
			}
		}
Here is what the Enum function output looks like:
IntelGFX BpP: 6291456 W: 24 H: 1024 Fr: 0 Flags: 768
Why is the ColorDepth for width, the frequency 0 and the flags the width!!
 
try to switch between the width and the flags values?
could it be a bug in the OS,C# or the API?
after all, we might be the first who try to use this api for XP using C#!

BTW, where did you find the values for the fields?
 
I'll try that but I don't think it will work. I found those values by looking on the net for ChangeDisplaySettings using google. All the examples I saw showed doing this procedure as I have done above but it does not work for some reason on XP or win98.
 
IT WORKS.
Only left to add the Frequency.

C#:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices; 

namespace ScreenResolution
{
	
	public class Form1 : System.Windows.Forms.Form
	{
		
		
		
		public enum DMDO
		{
			DEFAULT = 0,
			D90 = 1,
			D180 = 2,
			D270 = 3
		}

		[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
		struct DEVMODE
		{
            public const int DM_PELSWIDTH = 0x80000;
			public const int DM_PELSHEIGHT = 0x100000;		
			private const int CCHDEVICENAME = 32;
			private const int CCHFORMNAME = 32;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHDEVICENAME)]
			public string dmDeviceName;
			public short dmSpecVersion;
			public short dmDriverVersion;
			public short dmSize;
			public short dmDriverExtra;
			public int dmFields;

			public int dmPositionX;
			public int dmPositionY;
			public DMDO dmDisplayOrientation;
			public int dmDisplayFixedOutput;

			public short dmColor;
			public short dmDuplex;
			public short dmYResolution;
			public short dmTTOption;
			public short dmCollate;
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHFORMNAME)]
			public string dmFormName;
			public short dmLogPixels;
			public int dmBitsPerPel;
			public int dmPelsWidth;
			public int dmPelsHeight;
			public int dmDisplayFlags;
			public int dmDisplayFrequency;
			public int dmICMMethod;
			public int dmICMIntent;
			public int dmMediaType;
			public int dmDitherType;
			public int dmReserved1;
			public int dmReserved2;
			public int dmPanningWidth;
			public int dmPanningHeight;
		}

		//--------------------------------\

		
		
		[DllImport("user32.dll", CharSet=CharSet.Auto)]
		//static extern int ChangeDisplaySettings( DEVMODE lpDevMode,  int dwFlags);
		
		// should I use this line?
		static extern int ChangeDisplaySettings( [In] ref DEVMODE lpDevMode,  int dwFlags);

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

	
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.Size = new System.Drawing.Size(300,300);
			this.Text = "Form1";
		}
		#endregion

	
	
		static void Main() 
		{
			Form1 r = new Form1();
			r.ChangeRes();
			Application.Run(new Form1());
		}
      
		void ChangeRes()
		{
			
			Form1 t = new Form1();
	
			long RetVal=0;
			
			DEVMODE dm = new DEVMODE();
        
			dm.dmSize= (short)Marshal.SizeOf(typeof(DEVMODE));
				
			dm.dmPelsWidth = 1024;
            dm.dmPelsHeight= 768;
		
			dm.dmFields = DEVMODE.DM_PELSWIDTH | DEVMODE.DM_PELSHEIGHT;

			
			RetVal = ChangeDisplaySettings(ref dm, 0);
			
		
		}

	}
}
 
I myself am not going to mess with the frequency. I read that you can REALLY mess things up.

Good job though, so far. I'll try it later.
 
aewarnick, There is no need to mess things up.
just do the following changes:

C#:
public const int DM_DISPLAYFREQUENCY = 0x400000;
.
.
.
dm.dmDisplayFrequency=85;
dm.dmFields = DEVMODE.DM_PELSWIDTH | DEVMODE.DM_PELSHEIGHT | DEVMODE.DM_DISPLAYFREQUENCY;
 
Setting the Frequency to an invalid(unsupported) value will have "unexpected" results. I you use then EnumDisplaySettings it will give you a DEVMODE with the current settings which you can just change the properties you want and reset it with ChangeDisplaySettings

Try
C#:
Const int CDS_UPDATEREGISTRY = &H1
Const int CDS_TEST = &H4

RetVal = ChangeDisplaySettings(ref dm, CDS_UPDATEREGISTRY);
Remember to change it back afterwards though, of course if you're doing this just so your app looks the same on any computer then this still won't work because video cards have different Twips Per Pixel counts.
ie. I have 2 computers at 1024x768 but the other can fit less on the screen then this one because it has 12tpp but this has 15tpp

I would only use this for a fullscreen GDI app or a utility program that can change the resolution
 
Back
Top