修改屏幕分辨率时如何枚举显示器支持的所有显示模式

我想用C#程序设置屏幕分辨率及刷新频率,程序中必须检查,不允许设置到显示器不支持的模式上,以免有可能损坏显示器,请问怎样才能列出显示器支持的所有显示模式?
---------------------------------------------------------------

// ScreenMode.cs - 使用API枚举并设置显示模式

namespace Skyiv
{
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class ScreenMode : Form
{
enum DMDO { DEFAULT = 0, D90 = 1, D180 = 2, D270 = 3 }

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct DEVMODE
{
public const int DM_BITSPERPEL = 0x040000;
public const int DM_PELSWIDTH = 0x080000;
public const int DM_PELSHEIGHT = 0x100000;
public const int DM_DISPLAYFREQUENCY = 0x400000;
private const int CCHDEVICENAME = 32;
private const int CCHFORMNAME = 32;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
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 DMDO dmDisplayOrientation;
public int dmDisplayFixedOutput;

public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
public string dmFormName;
public short dmLogPixels;
public int 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 override string ToString()
{
return string.Format
(
"{0,4}×{1,-4} {2,2}Bits {3,3}Hz [{4}]",
dmPelsWidth,
dmPelsHeight,
dmBitsPerPel,
dmDisplayFrequency,
dmDeviceName
);
}
}

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool EnumDisplaySettings(int lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int ChangeDisplaySettings([In] ref DEVMODE lpDevMode, int dwFlags);

ListBox lbxPels;

// 构造函数
public ScreenMode()
{
Text = "显示属性";

lbxPels = new ListBox();
lbxPels.Parent = this;
lbxPels.Dock = DockStyle.Fill;
lbxPels.BeginUpdate();
DEVMODE DevMode = new DEVMODE();
for (int i = 0; EnumDisplaySettings(0, i, ref DevMode); i++)
{
lbxPels.Items.Add(DevMode);
}
lbxPels.EndUpdate();

Button btnSet = new Button();
btnSet.Parent = this;
btnSet.Text = "设置显示模式";
btnSet.Dock = DockStyle.Top;
btnSet.Click += new EventHandler(SetScrnMode);

Button btnGet = new Button();
btnGet.Parent = this;
btnGet.Text = "当前显示属性";
btnGet.Dock = DockStyle.Top;
btnGet.Click += new EventHandler(GetScrnInfo);
}

// 设置显示模式
void SetScrnMode(object sender, EventArgs e)
{
if (lbxPels.SelectedItem != null)
{
DEVMODE DevMode = (DEVMODE)lbxPels.SelectedItem;
ChangeDisplaySettings(ref DevMode, 0);
}
}

// 当前显示属性
void GetScrnInfo(object sender, EventArgs e)
{
Screen scrn = Screen.PrimaryScreen;
MessageBox.Show(
string.Format
(
"主设备: {1}{0}边 界: {2}{0}工作区: {3}{0}设备名: {4}",
Environment.NewLine,
scrn.Primary,
scrn.Bounds,
scrn.WorkingArea,
scrn.DeviceName
),
"当前显示属性",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}

// 程序入口
static void Main()
{
Application.Run(new ScreenMode());
}
}
}

Published At
Categories with Web编程
Tagged with
comments powered by Disqus