C# 中动态设定屏幕的显示方式和分辨率

       在Windows系统中想要通过代码动态设定屏幕的显示方式和分辨率,就需要调用windows提供的API,不同的Windows系统,API可能会有点不一样,但大体上相同。要实现这个功能需要使用win32 API 中的EnumDisplaySettings,ChangeDisplaySettings  这两个函数。

1.EnumDisplaySettings 读取当前显示设置,并枚举所有受支持的显示设置。

2.ChangeDisplaySettings 设定新的显示设置

这两个 API 都具有指向 DEVMODE 结构的指针,所以需要先定义DEVMODE结构体,这个结构体的定义需要和系统相匹配,看代码

    [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;
    }
}

接下来需要定义一个调用win32 API 功能的类,用户读取和设定系统中屏幕的相关信息

    public class WinAPI
    {
        // 平台调用的申明
        [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;
    }

然后定义一个对对屏幕进行操作的通用类

   /// <summary>
    /// 屏幕设置
    /// </summary>
    public static class ScreenSetting
    {
        /// <summary>
        /// 改变分辨率
        /// </summary>
        public static void 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 != WinAPI.EnumDisplaySettings(null, WinAPI.ENUM_CURRENT_SETTINGS, ref devmode))
            {
                devmode.dmPelsWidth = width;
                devmode.dmPelsHeight = height;

                // 改变屏幕分辨率
                int iRet = WinAPI.ChangeDisplaySettings(ref devmode, WinAPI.CDS_TEST);
                //int iRet = NativeMethods.ChangeDisplaySettings(ref devmode, 0);
                if (iRet == WinAPI.DISP_CHANGE_FAILED)
                {
                    MessageBox.Show("不能执行你的请求", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    iRet = WinAPI.ChangeDisplaySettings(ref devmode, WinAPI.CDS_UPDATEREGISTRY);

                    switch (iRet)
                    {
                        // 成功改变
                        case WinAPI.DISP_CHANGE_SUCCESSFUL:
                            {
                                break;
                            }
                        case WinAPI.DISP_CHANGE_RESTART:
                            {
                                MessageBox.Show("你需要重新启动电脑设置才能生效", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                break;
                            }
                        default:
                            {
                                MessageBox.Show("改变屏幕分辨率失败", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                break;
                            }
                    }
                }
            }
        }

        /// <summary>
        /// 改变显示方式
        /// </summary>
        /// <param name="displayOrientation"></param>
        public static void ChangeDisplayOrientation(int displayOrientation)
        {
            // 初始化 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 != WinAPI.EnumDisplaySettings(null, WinAPI.ENUM_CURRENT_SETTINGS, ref devmode))
            {
                int height = 0;
                int width = 0;
                switch (devmode.dmDisplayOrientation)
                {
                    case WinAPI.DMDO_DEFAULT:
                        height = devmode.dmPelsHeight;
                        width = devmode.dmPelsWidth;
                        break;
                    case WinAPI.DMDO_270:
                        width = devmode.dmPelsHeight;
                        height = devmode.dmPelsWidth;
                        break;
                    case WinAPI.DMDO_180:
                        height = devmode.dmPelsHeight;
                        width = devmode.dmPelsWidth;
                        break;
                    case WinAPI.DMDO_90:
                        width = devmode.dmPelsHeight;
                        height = devmode.dmPelsWidth;
                        break;
                    default:
                        // unknown orientation value
                        break;
                }

                int temp = devmode.dmPelsHeight;
                devmode.dmPelsHeight = devmode.dmPelsWidth;
                devmode.dmPelsWidth = temp;
                if (devmode.dmDisplayOrientation != displayOrientation)
                {
                    switch (displayOrientation)
                    {
                        case WinAPI.DMDO_DEFAULT:
                            devmode.dmPelsHeight = height;
                            devmode.dmPelsWidth = width;
                            devmode.dmDisplayOrientation = WinAPI.DMDO_DEFAULT;
                            break;
                        case WinAPI.DMDO_270:
                            devmode.dmPelsHeight = width;
                            devmode.dmPelsWidth = height;
                            devmode.dmDisplayOrientation = WinAPI.DMDO_270;
                            break;
                        case WinAPI.DMDO_180:
                            devmode.dmPelsHeight = height;
                            devmode.dmPelsWidth = width;
                            devmode.dmDisplayOrientation = WinAPI.DMDO_180;
                            break;
                        case WinAPI.DMDO_90:
                            devmode.dmPelsHeight = width;
                            devmode.dmPelsWidth = height;
                            devmode.dmDisplayOrientation = WinAPI.DMDO_90;
                            break;
                        default:
                            // unknown orientation value
                            break;
                    }
                }
                else
                {
                    return;
                }

                // 改变屏幕显示方式
                int iRet = WinAPI.ChangeDisplaySettings(ref devmode, 0);
                if (iRet == WinAPI.DISP_CHANGE_FAILED)
                {
                    MessageBox.Show("不能执行你的请求", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    iRet = WinAPI.ChangeDisplaySettings(ref devmode, WinAPI.CDS_UPDATEREGISTRY);

                    switch (iRet)
                    {
                        // 成功改变
                        case WinAPI.DISP_CHANGE_SUCCESSFUL:
                            {
                                break;
                            }
                        case WinAPI.DISP_CHANGE_RESTART:
                            {
                                MessageBox.Show("你需要重新启动电脑设置才能生效", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                break;
                            }
                        default:
                            {
                                MessageBox.Show("改变屏幕分辨率失败", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                break;
                            }
                    }
                }
            }
        }
    }

最后就是对所完成的功能进行测试,效果如下

C# 中动态设定屏幕的显示方式和分辨率

 

C# 中动态设定屏幕的显示方式和分辨率 

 

 

上一篇:Linux运维脚本


下一篇:2.安装Spark与Python练习