在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;
}
}
}
}
}
}
最后就是对所完成的功能进行测试,效果如下