因为最近在MSDN论坛和stackflow中看到一些朋友经常问到这个问题,所以写这篇文章来帮助大家遇到相同问题的时候可以很快的得到解决,下面就不啰嗦了,直接看代码如何解决这个问题的。

首先,大家应该明确,现在没有可用的API来给我们动态地设置屏幕分辨率,我们要实现这个需求,我们只能在C#程序中调用Win32 API函数来解决这个问题的,这里用C#代码调用Win32 API 就涉及到一个问题的,即.NET 互操作性的问题,关于这个大家可以参考我的互操作性系列文章。这里我就不过多解释了。

我们要解决这个问题,首先大家肯定也会遇到一个经常遇到的问题,即如何获得用户的分辨率,对于这个问题,.NET中提供的单独的类给我们调用,我们可以使用Screen这个类,具体看下面的示例代码:

  Screenscreen = Screen.PrimaryScreen;           int screenWidth= screen.Bounds.Width;           int screenHeight = screen.Bounds.Height;

然后就是如何改变屏幕的分辨率呢?要更改显示设置可以通过使用两个 Win32 API 来完成,这两个 API 都具有指向 DEVMODE 结构的指针,它们分别包含与显示设置有关的所有信息:

第一步、我们要先定义DEVMODE 结构体,该结构的结构必须与DEVMODE的结构一致,下面是C#中对DEVMODE 结构体的定义代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 映射 DEVMODE 结构
     // 可以参照 DEVMODE结构的指针定义:
     // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
     public  struct  DEVMODE
     {
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
         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  dmDisplayOrientation;
         public  int  dmDisplayFixedOutput;
         public  short  dmColor;
         public  short  dmDuplex;
         public  short  dmYResolution;
         public  short  dmTTOption;
         public  short  dmCollate;
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
         public  string  dmFormName;
         public  short  dmLogPixels;
         public  short  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;
     };

第二步、在托管环境下对Win 32 函数进行声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Win32 函数在托管环境下的声明
     public  class   NativeMethods
     {
         // 平台调用的申明
         [DllImport( "user32.dll" )]
         public  static  extern  int  EnumDisplaySettings(
           string  deviceName,  int  modeNum,  ref  DEVMODE devMode);
         [DllImport( "user32.dll" )]
         public  static  extern  int  ChangeDisplaySettings(
               ref  DEVMODE devMode,  int  flags);
         // 控制改变屏幕分辨率的常量
         public  const  int  ENUM_CURRENT_SETTINGS = -1;
         public  const  int  CDS_UPDATEREGISTRY = 0x01;
         public  const  int  CDS_TEST = 0x02;
         public  const  int  DISP_CHANGE_SUCCESSFUL = 0;
         public  const  int  DISP_CHANGE_RESTART = 1;
         public  const  int  DISP_CHANGE_FAILED = -1;
         // 控制改变方向的常量定义
         public  const  int  DMDO_DEFAULT = 0;
         public  const  int  DMDO_90 = 1;
         public  const  int  DMDO_180 = 2;
         public  const  int  DMDO_270 = 3;
     }

第三步、调用EnumDisplaySettingsChangeDisplaySettings这两个函数来实现动态改变屏幕分辨率,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 改变分辨率
         public  ChangeResolution( int  width,  int  height)
         {
             // 初始化 DEVMODE结构
             DEVMODE devmode =  new  DEVMODE();
             devmode.dmDeviceName =  new  String( new  char [32]);
             devmode.dmFormName =  new  String( new  char [32]);
             devmode.dmSize = ( short )Marshal.SizeOf(devmode);
             if  (0 != NativeMethods.EnumDisplaySettings( null , NativeMethods.ENUM_CURRENT_SETTINGS,  ref  devmode))
             {
                 devmode.dmPelsWidth = width;
                 devmode.dmPelsHeight = height;
                 // 改变屏幕分辨率
                 int  iRet = NativeMethods.ChangeDisplaySettings( ref  devmode, NativeMethods.CDS_TEST);
                 if  (iRet == NativeMethods.DISP_CHANGE_FAILED)
                 {
                     MessageBox.Show( "不能执行你的请求" "信息" , MessageBoxButtons.OK, MessageBoxIcon.Information);
                 }
                 else
                 {
                     iRet = NativeMethods.ChangeDisplaySettings( ref  devmode, NativeMethods.CDS_UPDATEREGISTRY);
                     switch  (iRet)
                     {
                             // 成功改变
                         case  NativeMethods.DISP_CHANGE_SUCCESSFUL:
                             {
                                 break ;
                             }
                         case  NativeMethods.DISP_CHANGE_RESTART:
                             {
                                 MessageBox.Show( "你需要重新启动电脑设置才能生效" "信息" , MessageBoxButtons.OK, MessageBoxIcon.Information);
                                 break ;
                             }
                         default :
                             {
                                 MessageBox.Show( "改变屏幕分辨率失败" "信息" , MessageBoxButtons.OK, MessageBoxIcon.Information);
                                 break ;
                             }
                     }
                 }
             }
         }

为了大家更加形象地看到程序的运行结果,下面是一个演示效果: