[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 結構體的定義代碼:

// 映射 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;
    };
View Code

第二步、在托管環境下對Win 32 函數進行聲明:

// 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;
    }
View Code

第三步、調用EnumDisplaySettingsChangeDisplaySettings這兩個函數來實現動態改變屏幕分辨率,具體代碼如下:

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

為了大家更加形象地看到程序的運行結果,下面是一個演示效果:

實現源代碼下載:動態設置屏幕分辨率.zip

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM