在窗体上使用Windows XP风格的控件

上海市复旦大学0024信箱 王凯明 编译  
02-2-27 上午 11:22:09

一.概要

Windows XP开创了一种全新的Windows用户界面(UI),这种用户界面给用户一种现代化的、超时髦的感受。Windows XP新创了闪亮的具有圆形边角的控件以及极富未来派气息的进度条等具有新风格的控件。

而现在的Visual Studio.Net也具备了此类控件。那么开发者就想能否在自己开发的程序中使用这类超酷的控件呢。答案是肯定的,程序员所要做的仅仅是添加一些引用以及一个资源文件。本文就通过介绍一个实例向大家介绍如何在Visual Basic和Visual C#下将控件的Windows XP风格应用到自己的程序中。

注:本文介绍的控件风格特性只能在Windows XP下的运用程序中实现。

二.介绍

我们先来做一个有关控件风格的比较。

在Windows XP下的控件具有一种全新的外观。图示如下:

diag6_1

而在Visual Studio.Net中提供的控件虽然和Windows XP下的是同样的,但是它们的外观却截然不同。图示如下:

diag6_2

本文就向大家介绍如何使Visual Studio中的控件和Windows XP下的控件一样,具有超酷的外观、良好的用户界面。

你可以认为一个窗体由两个相互独立的部分组成:一个客户区以及一个非客户区。所有在Windows XP操作系统上运行的程序都有一个非客户区,它包括:窗体框架、标题栏以及的非客户区的滚动条。操作系统会自动给非客户区应用Windows XP风格,所以尽管什么也没做,你也可以看到自己的程序在Windows XP上运行时具有新风格的窗体框架、标题栏以及滚动条。而我们真正要做的就是使客户区的控件也具有Windows XP的风格。

三.实现原理

非客户区的外观是由当前所应用的视觉风格决定的。一个运用程序或是操作系统的视觉风格是可以被更改的。就像上面提到的那样,当一个运用程序运行在Windows XP上时,窗体的滚动条以及标题栏就立即改变了外观风格。只要运用程序应用了版本为6.0的Comctl32.dll,那么其中的某些控件就是自动的呈现新的外观。

这类控件如下:

TextBox 控件ListView控件
RichTextBox控件TreeView控件
HScrollBar控件DateTimePicker控件
VScrollBar控件MonthCalendar控件
ProgressBar控件Splitter控件
TabControl控件TrackBar控件
MainMenu控件StatusBar控件
ContextMenu控件ToolBar控件
ComboBox 控件TreeView控件
DataGrid控件ListView控件
ListBox控件

其他的控件则需要一定的条件。确切地说,从System.Windows.Forms.ButtonBase类继承过来的控件(Button,RadioButton,GroupBox以及CheckBox等控件)有一个FlatStyle属性。这个属性表明控件应该先被绘制。通过设置这个属性,控件可以用以下几种方式来绘制:

属性描述
Flat控件为平坦的
Popup鼠标在控件上时,控件为三维的,否则为平坦的
Standard控件为三维的.
System控件的外观由用户的操作系统设置决定

你可以发现,当FlatStyle属性被设置为System后,控件的外观就由用户的操作系统设置所决定。这样的话,要是用户的操作系统为Windows XP,那么相应控件的外观就会呈现Windows XP的风格了。

当FlatStyle属性被设置为System后,能改变视觉风格的控件如下:

Button 控件
RadioButton 控件
CheckBox 控件
GroupBox 控件

最后,还有一些控件在Windows XP和Visual Studio下是一样的,这些控件如下:

Label 控件
LinkLabel 控件
DomainUpDown 控件
NumericUpDown 控件
CheckedListBox 控件

四.使用Manifest文件

如果你想在你的运用程序中运用Windows XP的外观效果,你必须给你的工程添加一个Manifest文件(在建立工程过程中用来确定资源的一个文件)。这个文件指明了在工程中应用版本为6.0的Comctl32.dll文件(只要这个文件存在)。版本为6.0的Comctl32.dll文件包括了一些新的控件以及一些控件的新特性,它和以前版本的最大的差异就是它支持控件外观效果的改变。

不像以前的版本,版本为6.0的Comctl32.dll是不可以被重新发布的。你只可以在包含它的操作系统中使用它的动态连接库(DLL)。Windows XP既包含了版本为5.0的,又包含了版本为6.0的(在默认的情况下,运用程序是用版本为5.0的Comctl32.dll的)。在版本为6.0的Comctl32.dll中,包含了用户控件和一般控件。你只要改变和这些控件相关的dll文件,就可以使它们呈现出Winodws XP的外观风格了。

为了和用户的计算机操作系统相协调,你必须在你的运用程序中建立一个Manifest文件来明确的指定其窗体控件使用的是版本为6.0的Comctl32.dll。该Manifest文件是一个XML文件,它包含在你的程序中,作为一个资源,或是在可执行文件目录下的一个单独的文件。

因此,为了使你的运用程序具有像Windows XP那样的外观效果,你必须:

  1. 若控件有FlatStyle属性,则把它设置为FlatStyle.System
  2. 建立一个Manifest文件,将版本为6.0的Comctl32.dll捆绑到你的运用程序中(下面的例子中的Manifest文件可以将该Comctl32.dll捆绑到任何用Visual Studio.Net建立的运用程序中)
  3. 把这个资源(Manifest文件)添加到你的可执行文件并进行重建

五.将Windows XP视觉风格应用到控件中

学会应用Windows XP视觉风格的最简单的方法就是学习做一个实例。本文最后就向大家介绍任何建立一个简单的运用程序并使它的窗体上的控件具有Windows XP视觉风格。

接下来,我们要做的就是:

  1. 建立一个运用程序的工程,并在窗体上添加一些控件
  2. 建立一个Manifest文件,将所需的DLL捆绑到你的运用程序中
  3. 将该Manifest文件存放在可执行文件目录下
  4. 添加一项资源(Manifest文件)到可执行文件

下面就开始创建新的工程……

创建工程

1.新建一个Windows运用程序工程。(注:请记住工程名以及工程存放的目录,下面有用)

2.从工具箱里拖以下控件到窗体上并将它们排列好:

Button 控件
RadioButton 控件
ProgressBar 控件
CheckBox 控件
Label 控件

(注:虽然Label控件的外观不会改变,它也被拖放到窗体上以作对比)

3.将Button,RadioButton,CheckBox等控件的FlatStyle属性设置为System。(技巧:你可以在点击每个控件的同时按下Ctrl键,这样就可以同时选中这三个控件。然后,在FlatStyle属性的下拉框中选定System即可)

4.双击Button控件以给它添加事件处理函数,代码编辑器会自动打开。

5.添加以下一些代码,设置ProgressBar控件的Value属性,那样你就可以看到新的一个进度条了:

' Visual Basic
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
ProgressBar1.Value = 50
End Sub
// C#
private void button1_Click(object sender, System.EventArgs e)
{
    progressBar1.Value = 50;
}

6.从“生成”菜单上选择“生成”选项。

7.最后,全部保存。

建立Manifest文件

建立一个XML文件,将正确的版本的Comctl32.dll捆绑到你的运用程序中。

新建并编辑Manifest文件:

1.在解决方案资源管理器中,右击工程名:添加->添加新项

2.在添加新项对话框中完成以下工作:

A.在左边的方块中点击“本地项目项”。
B.在右边的方块中选定“文本文件”。
C.在名称框中以下面的方式命名文件:<Executable Name>.exe.manifest。因此,如果你的运用程序名为MyXPApp,那么你应该将这个XML文件命名为MyXPApp.exe.manifest。

3.点击“打开”按钮,文本编辑器中打开了你新建的文件。

4.将下面的XML添加到该文本文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="Microsoft.Winweb.<Executable Name>"
type="win32"
/>
<description>.NET control deployment tool</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

5.将上面第五行中的<Executable Name>替换成你的运用程序名即可。

6.从“生成”菜单上选择“生成”选项。

7.最后,全部保存。

将该Manifest文件存放在可执行文件所在目录

现在,将你建立的Manifest文件拷贝到可执行文件所在的目录。

移动Manifest文件

1.打开资源管理器,到Visual Studio解决方案所在的目录。在这个目录里,你应该看到刚才建立的Manifest文件。(命名为<Executable Name>.exe.manifest) 2.选择该文件,并拷贝它。 3.将当前目录转到obj->Debug,在这个目录下,你可以看到可执行文件。 4.将拷贝的Manifest文件粘贴到该目录下。

添加Manifest文件到可执行文件

接下来,在Visual Studio中打开可执行文件,并将Manifest文件作为一项资源添加到其中。

以资源方式添加Manifest文件

  1. 在Visual Studio中,在“文件”菜单下选择:打开->文件。
  2. 转到可执行文件所在的目录,并双击打开可执行文件。
  3. 在设计框中右击可执行文件名,选择“添加资源”。
  4. 在添加资源对话框中选择“导入”。
  5. 转到刚建立的Manifest文件所在的目录。(和可执行文件在同一个目录下)
  6. 双击打开Manifest文件,同时自定义资源类型对话框打开。
  7. 在资源类型对话框中,键入RT_MANIFEST即可。
  8. 在属性窗口,将ID设置为1。
  9. 最后,就是全部保存。

尝试新成果

好了,到处为止,新的程序可以运行了。当你的运用程序运行在Windows XP下时,窗体上的控件将显示出富有未来派气息的Windows XP视觉风格。同时,你也可以试试按下按钮,看看新型的进度条的样子。

然而,当你的程序运行在其他的操作系统下时,那个Manifest文件应该被忽略,因为在其他操作系统上是没有版本为6.0的Comctl32.dll文件的。所以,窗体上的控件又会和以前的一样了。

接下来的步骤

对于以上问题,我有更好的、更健壮的解决方案。那就是先进行操作系统的版本检查,然后根据检查结果,动态调用可执行文件下的Manifest文件从而动态的将FlatStyle属性设置为System。

以下给出了逻辑上的代码:

' Visual Basic
Private Sub RecursivelyFormatForWinXP(control As Control)
Dim x As Integer
For x = 0 To control.Controls.Count - 1
' 如果控件是从ButtonBase继承过来的
' 将FlatStyle属性设置为System
If control.Controls(x).GetType().BaseType Is _
GetType(ButtonBase) Then
CType(control.Controls(x), ButtonBase).FlatStyle = _
FlatStyle.System
End If

' 如果控件中包含了其他控件,那么进行同样的操作
If control.Controls.Count > 0 Then
RecursivelyFormatForWinXP(control.Controls(x))
End If
Next x
End Sub
// C#
private void RecursivelyFormatForWinXP(Control control)
{
    for (int x = 0; x < control.Controls.Count; x++)
    {
        // 如果控件是从ButtonBase继承过来的 
        // 将FlatStyle属性设置为System 
        if (control.Controls[x].GetType().BaseType == typeof(ButtonBase))
        {
            ((ButtonBase)control.Controls[x]).FlatStyle = FlatStyle.System;
        }

        // 如果控件中包含了其他控件,那么进行同样的操作 
        if (control.Controls.Count > 0)
        {
            RecursivelyFormatForWinXP(control.Controls[x]);
        }
    }
}

另外,你需要修改Load事件处理函数,从而判断程序是否运行在Windows XP下,Manifest文件是否要被用到:

' Visual Basic
Private Sub Form1_Load(sender As Object, e As System.EventArgs)
' 确定是在Windows XP下运行并且Manifest文件存在
If Environment.OSVersion.Version.Major > 4 And _
Environment.OSVersion.Version.Minor > 0 And _
File.Exists((Application.ExecutablePath + ".manifest")) Then
' 遍历各个控件
Dim x As Integer
For x = 0 To (Me.Controls.Count) - 1
' 如果控件是从ButtonBase继承过来的
' 将FlatStyle属性设置为System
If Me.Controls(x).GetType().BaseType = _
GetType(ButtonBase) Then
CType(Me.Controls(x), ButtonBase).FlatStyle = _
FlatStyle.System
End If
RecursivelyFormatForWinXP(Me.Controls(x))
Next x
End If
End Sub
// C# 
private void Form1_Load(object sender, System.EventArgs e)
{
    // 确定是在Windows XP下运行并且Manifest文件存在 
    if (Environment.OSVersion.Version.Major > 4
    & Environment.OSVersion.Version.Minor > 0
    & File.Exists(Application.ExecutablePath + ".manifest"))
    {
        // 遍历各个控件 
        for (int x = 0; x < this.Controls.Count; x++)
        {
            // 如果控件是从ButtonBase继承过来的 
            // 将FlatStyle属性设置为System 
            if (this.Controls[x].GetType().BaseType == typeof(ButtonBase))
            {
                ((ButtonBase)this.Controls[x]).FlatStyle = FlatStyle.System;
            }
            RecursivelyFormatForWinXP(this.Controls[x]);
        }
    }
}

六.文章总结

在本文中,我给大家展示了以下几方面的内容:

  1. 具有Windows XP视觉风格的控件和Visual Studio中的标准控件的外观是截然不同的。
  2. 你可以将大部分的控件的外观设计成和Windows XP中的一样。
  3. 对于大多数的控件,这个设计过程只需要将它们捆绑到一定版本(版本6.0)的Comctl32.dll即可;对于其他的,你需要将FlatStyle属性设置为System;最后,还有一部分根本不用修改。
  4. 你可以编写检查操作系统版本的代码,从而确定Manifest文件是否需要用来动态设置各个控件的相应属性。

(网页编辑:编程浪子)

Contributors: FHL