因为最近在MSDN论坛和stackflow中看到一些朋友经常问到这个问题,所以写这篇文章来帮助大家遇到相同问题的时候可以很快的得到解决,下面就不啰嗦了,直接看代码如何解决这个问题的。
首先,大家应该明确,现在没有可用的API来给我们动态地设置屏幕分辨率,我们要实现这个需求,我们只能在C#程序中调用Win32 API函数来解决这个问题的,这里用C#代码调用Win32 API 就涉及到一个问题的,即.NET 互操作性的问题,关于这个大家可以参考我的互操作性系列文章。这里我就不过多解释了。
我们要解决这个问题,首先大家肯定也会遇到一个经常遇到的问题,即如何获得用户的分辨率,对于这个问题,.NET中提供的单独的类给我们调用,我们可以使用Screen这个类,具体看下面的示例代码:
Screenscreen = Screen.PrimaryScreen; int screenWidth= screen.Bounds.Width; int screenHeight = screen.Bounds.Height;
然后就是如何改变屏幕的分辨率呢?要更改显示设置可以通过使用两个 Win32 API 来完成,这两个 API 都具有指向 DEVMODE 结构的指针,它们分别包含与显示设置有关的所有信息:
使用 EnumDisplaySettings 读取当前显示设置,并枚举所有受支持的显示设置。
使用 ChangeDisplaySettings 切换到新的显示设置。
第一步、我们要先定义DEVMODE 结构体,该结构的结构必须与DEVMODE的结构一致,下面是C#中对DEVMODE 结构体的定义代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
// 映射 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;
};
|
第二步、在托管环境下对Win 32 函数进行声明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 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;
}
|
第三步、调用EnumDisplaySettings和ChangeDisplaySettings这两个函数来实现动态改变屏幕分辨率,具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
// 改变分辨率
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
;
}
}
}
}
}
|
为了大家更加形象地看到程序的运行结果,下面是一个演示效果:
附件:http://down.51cto.com/data/2362889
本文转自LearningHard 51CTO博客,原文链接:http://blog.51cto.com/learninghard/1207708,如需转载请自行联系原作者