zoukankan      html  css  js  c++  java
  • [C# 开发技巧系列]如何动态设置屏幕分辨率

    [C# 开发技巧系列]如何动态设置屏幕分辨率

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

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

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

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

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

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

     View Code
    // 映射 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 函数进行声明:

     View Code
    // 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这两个函数来实现动态改变屏幕分辨率,具体代码如下:

     View Code
    // 改变分辨率
            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;
                                }
                        }
                    }
                }
            }

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

    实现源代码下载:动态设置屏幕分辨率.zip


        如果,您认为阅读这篇博客对你有帮助,点击一下左下角的[推荐]
        如果,你想了解我的动态,点击一下左下角的[关注我]
        因为,你们的支持正是我学习的动力 
        如需转载,请注明出处

        如果对文章有任何问题,都可以再评论中留言,我会尽可能的答复您,谢谢你的阅读

     
  • 相关阅读:
    day10 Java学习(开发工具.Eclipse)
    day9 Java学习(面向对象Package关键字)
    day8 Java学习(面向对象.多态&接口)
    day7 Java学习(面向对象.继承)
    day5 Java学习(面向对象)
    day4 Java学习(数组)
    day3 Java学习(循环结构)
    day2 Java学习(位运算符)
    2019-05-26 java学习日记
    2019-05-25 java学习日记
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3094909.html
Copyright © 2011-2022 走看看