动态屏幕分辨率






4.45/5 (50投票s)
在C#中设置屏幕分辨率。
引言
当我在为一个测试套件开发一些胖客户端应用程序时,我很难设置动态屏幕分辨率。我想我们大多数人都遇到过这种情况,或者在我们的工程生命周期中的某个地方面临过这种情况。因为,众所周知,用户屏幕的分辨率可能与开发环境屏幕的分辨率不同。
本文旨在提供我所发现的解决上述挑战的方案。
以下部分将讨论
- 如何获取最终用户的屏幕分辨率
- 如何将用户屏幕分辨率更改为产品兼容的分辨率
- 如何保护用户的屏幕分辨率
如何获取最终用户的屏幕分辨率
通过 .NET framework 自带的 Screen
类可以轻松访问用户屏幕。并且可以通过 Screen
类中的静态 Screen.PrimaryScreen
属性访问当前用户的屏幕分辨率。
public static Screen PrimaryScreen {get;}
上述属性是只读的,并返回一个 Screen
类型。下面给出的逻辑演示了如何使用 Screen
类型来访问用户的屏幕分辨率。
Screen screen = Screen.PrimaryScreen;
int S_width=screen.Bounds.Width;
int S_height=screen.Bounds.Height;
如何将用户屏幕分辨率更改为产品兼容的分辨率
在进入我们的下一个目标之前,让我谈谈这个实现中非托管的部分。与传统语言不同,.NET framework 在利用托管和非托管代码时有一个独特的步骤。就我个人而言,在编写这篇文章时,我从未找到任何可以处理此分辨率的托管代码。这让我开始考虑探索一些 Win32 API。
在继续之前,我希望您具备以下方面的实践或理论知识:COM 互操作服务、Attribute、DLL 导入属性 和 Platform Invoke。
由于本文的范围仅限于托管代码,因此我不会讨论任何关于非托管代码的内容。但是,尽管如此,我们可以使用 DllImport
属性将非托管代码的定义读取到您的托管环境中。在这种情况下,我们将使用 User32.dll
API,它有助于动态分辨率,并且有两个与更改屏幕分辨率相关的函数。
EnumDisplaySettings
ChangeDisplaySettings
class User32
{
[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;
}
众所周知,[DllImport("user32.dll")]
是在我们的托管环境中注入非托管实现之前的一个显式基础。
public static extern int EnumDisplaySettings
(string deviceName, int modeNum, ref DEVMODE devMode);
DEVMODE
是一个结构,在平台文档中对此进行了说明,并且包含在 Visual Studio .NET 中。该结构在 C# 中定义。
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
...
}
您可以查看附加的源代码,并将此逻辑应用于您想要的任何事件。
请注意,这些类型具有正确的大小,并且固定长度的字符串已得到适当的定义。在这种情况下,WORD
映射到 short
,DWORD
映射到 int
,并且 short
保持为 short
。
DEVMODE dm = new DEVMODE();
dm.dmDeviceName = new String (new char[32]);
dm.dmFormName = new String (new char[32]);
dm.dmSize = (short)Marshal.SizeOf (dm);
if (0 != User32.EnumDisplaySettings (null,
User32.ENUM_CURRENT_SETTINGS, ref dm))
{
此时,DEVMODE
结构将使用默认设置进行装饰,并且可以在任何实例中对其进行修改。
dm.dmPelsWidth = iWidth;
dm.dmPelsHeight = iHeight;
int iRet = User32.ChangeDisplaySettings (
ref dm, User32.CDS_UPDATEREGISTRY);
封闭的代码块以稍微不同的方式处理各种错误情况。我建议您查看完整的源文件,看看它是如何工作的。这就是全部。
如何保护用户的屏幕分辨率
最后,在我们继续之前,保护用户的默认屏幕分辨率是我们的责任。为了做到这一点,您可能需要使用一些静态成员或类来保存用户屏幕分辨率,并在您完成执行后将其恢复。
请参阅本文顶部的下载链接以获取源代码。