首页  编辑  

C#调用API更改显示器分辨率

Tags: /C#/   Date Created:
支持多显示器修改分辨率

Program.cs
using Resolution;
internal class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");
        Console.WriteLine(PrmaryScreenResolution.ChangeResolution(1680, 1050, 0));
        Console.WriteLine(PrmaryScreenResolution.ChangeResolution(1920, 1080, 0));
        Console.WriteLine(PrmaryScreenResolution.ChangeResolution(1680, 1050, 1));
        Console.WriteLine(PrmaryScreenResolution.ChangeResolution(1920, 1080, 1));
    }
}

Display.cs:

using System;
using System.Runtime.InteropServices;

namespace Resolution
{
    [StructLayout(LayoutKind.Sequential)]
    public struct DEVMODE1
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string dmDeviceName;
        public short dmSpecVersion;
        public short dmDriverVersion;
        public short dmSize;
        public short dmDriverExtra;
        public int dmFields;

        public short dmOrientation;
        public short dmPaperSize;
        public short dmPaperLength;
        public short dmPaperWidth;

        public short dmScale;
        public short dmCopies;
        public short dmDefaultSource;
        public short dmPrintQuality;
        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;
    };

    public struct DISPLAY_DEVICE
    {
        public int cb;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string deviceName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string deviceString;
        public uint StateFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string deviceID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string deviceKey;
    }

    class User_32
    {
        [DllImport("user32.dll")]
        public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);

        [DllImport("user32.dll")]
        public static extern int ChangeDisplaySettingsEx(string deviceName, ref DEVMODE1 devMode, int hwnd, int flags, int lParam);

        [DllImport("User32.dll")]
        public static extern int EnumDisplayDevices(string lpszDeviceName, int iDevNum, ref DISPLAY_DEVICE device, uint dwFlags);

        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 class PrmaryScreenResolution
    {
        static public string ChangeResolution(int width, int height, int index)
        {

            DEVMODE1 dm = GetDevMode1();
            DISPLAY_DEVICE dd = new DISPLAY_DEVICE();
            dd.cb = (short)Marshal.SizeOf(dd);

            // 根据索引,获取显示器设备名称
            User_32.EnumDisplayDevices(null, index, ref dd, 0);
            // 获取指定显示器的当前设置
            int ret = User_32.EnumDisplaySettings(dd.deviceName, User_32.ENUM_CURRENT_SETTINGS, ref dm);
            if (0 != ret)  // 获取成功,则只修改分辨率,其余不变
            {
                dm.dmPelsWidth = width;
                dm.dmPelsHeight = height;

                int iRet = User_32.ChangeDisplaySettingsEx(dd.deviceName, ref dm, 0, User_32.CDS_TEST, 0);
                if (iRet == User_32.DISP_CHANGE_FAILED)
                {
                    return "Unable To Process Your Request. Sorry For This Inconvenience.";
                }
                else
                {
                    iRet = User_32.ChangeDisplaySettingsEx(dd.deviceName, ref dm, 0, User_32.CDS_UPDATEREGISTRY, 0);
                    switch (iRet)
                    {
                        //case User_32.DISP_CHANGE_SUCCESSFUL:
                        //{
                        //return "Ok";
                        //}
                        case User_32.DISP_CHANGE_RESTART:
                            {
                                return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.";
                            }
                        default:
                            {
                                return "Failed To Change The Resolution";
                            }
                    }

                }
            }
            else
            {
                return "Failed To Change The Resolution.";
            }
        }

        private static DEVMODE1 GetDevMode1()
        {
            DEVMODE1 dm = new DEVMODE1();
            dm.dmDeviceName = new String(new char[32]); ;
            dm.dmFormName = new String(new char[32]);
            dm.dmSize = (short)Marshal.SizeOf(dm);
            return dm;
        }
    }
}

参考: Powershell封装