給.NET中的Windows窗體加載Xp樣式
作者:Heath Stewart
翻譯:鄭佐
介紹
當Windows XP 帶着他特有的可視化樣式或者主題發佈時,許多人爲他擁有的華麗界面而興奮。然而,當.NET1.0正式版本發佈的時候,許多人包括我自己爲Windows 窗體不支持Windows XP 的可視化樣式而失望。我對可視化樣式的API函數和微軟的.NET框架開發文檔進行了一番研究,而後認識到爲.NET應用程序加上Xp樣式也不是很難。
下面的將通過一個簡單的程序來爲你的程序和控件加上Xp樣式。內容適用於一些擁有能實現Xp樣式的屬性的控件,通過這些屬性使他們產生Xp樣式,同時通知Windows系統爲你的應用程序和控件加上主題。
實現所需條件
你需要一些條件來實現這項功能:
1.Microsoft .NET Framework SDK(必須)
2.Microsoft Visual Studio .NET,他幫助你設計Windows窗體(可選)
3.Windows XP 操作系統(可選),支持主題的正式版本操作系統
進入正題
打開Visual Studio .NET 建立一個新的Windows 應用程序。在這裏我將使用C#來作爲編程語言,因此如果你使用Visual Basic.NET,你就需要轉換代碼。當你建好項目後,打開AssemblyInfo.cs文件,在AssemblyTitle,AssemblyDescription以及AssemblyVersion中填入值,修改AssemblyDelaySign的值爲true。同時你也要修改AssemblyKeyFile的值爲@”../../KeyFile.snk”,KeyFile.snk文件我們隨後回來創建或者拷貝一個。
當你按照上面所說的完成後,你的代碼看起來應該象下面:
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyTitle("Theme Test")]
[assembly: AssemblyDescription("Testing Windows XP Visual Styles.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyKeyFile(@"../../KeyFile.snk")]
[assembly: AssemblyKeyName("")]
現在,打開Form1.cs窗體設計界面加一些Windows窗體控件到上面,比如ListViews,Buttons,GroupBoxes,ProgressBars或者更多,下面列出了所有支持Xp樣式的孔件:
TextBox
RichTextBox
HScrollBar
VScrollBar
ProgressBar
TabControl
MainMenu
ContextMenu
ComboBox
DataGrid
ListBox
ListView
TreeView
DateTimePicker
MonthCalendar
Splitter
TrackBar
StatusBar
ToolBar
TreeView
ListView
對於這些控件,有些是默認就支持的,另外的一些特定的控件是從ButtonBase,GroupBox,或者Label繼承而來,你需要設置他們的FlatStyle屬性爲System,那些我會做一些簡短的說明。
當你編譯這個應用程序後,你會發現這個Windows Forms看上去不象帶有Xp樣式,要找到原因,請往下看。
Windows Xp樣式的顯示原理
簡單描述:Comctl32.dll,版本爲6。Comctl32.dll,或者那些普通控件使用了很長時間。這個動態連接庫被基礎控件使用,同時User32.Dll提供給用戶控件。在版本6的Comctl32.dll中,所有的控件都放入在裏面,因此他們都支持主題。但是新版本的Comctl32.dll不象上一個版本,要使用Windows XP樣式,你必須使用包含有Comctl32.dll的操作系統,比如Windows XP。
對於那些被支持的控件,他們的樣式是同一些特殊的主題資源相關的,而這些就是用來在客戶界面進行繪製。對於那些派生於ButtonBase,GroupBox和Lablel的控件必須把FlatStyle屬性設置成FlatStyle.System枚舉值,這樣系統就可以對他們進行繪製。
爲了使操作系統給我們的控件加主題樣式,你需要通知系統讓版本6的Comctl32.dll作爲默認。系統默認的使用的是版本5的Comctl32.dll,對於.NET的程序也是如此,但是我們會讓程序在執行時使用版本6的Comctl32.dll。
給你的項目增加一個XML文件,文件命取爲[你的應用程序名].exe.manifest,[你的應用程序名]指得就是項目編譯生成的主exe文件。設置編譯類型爲”None”。
假如你的AssemblyInfo.cs中的代碼就是上面提到的那樣,那麼新建的[你的應用程序名].exe.manifest文件應該爲下面的樣子:
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
version="1.0.0.0"
processorArchitecture="X86"
name="Theme Test"
type="win32" />
Testing Windows XP Visual Styles.
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*" />
你要適當的替換上面的”version”和”name”屬性的值,使他和你項目裏面的一樣,分別對應AssemblyVersion和AssemblyTitle屬性。那個”descryiption”元素也要同你的AssemblyDescription屬性符合。
接下去,打開命令提示窗口修改你的項目輸出路徑,應該把”bin/Debug”作爲項目路徑根目錄。假設你已經加了sn.exe強名稱工具的路徑到你的系統環境變量,那麼在命令行中輸入如下:
sn.exe –k ../../KeyFile.snk
上面的步驟會生成一個KeyFile.snk公鑰文件,爲了使你的程序集成爲強類型程序集這個公鑰是必須的。這個在許多情況下是必須需的。
最後一步添加Mnifest信息
你現在要在項目文件輸出的所在目錄。在我的例子中是一個簡單的WindowsApplication1.exe文件,接下去會講到他。
現在,退回到Visul Studio.NET,點擊文件菜單—>打開,瀏覽到你的應用程序比如WindowsApplication1.exe,點擊打開他我們會看到一個資源文件管理樹。
1.右鍵在根節點上點擊選擇“添加資源”。
2.點擊“導入”按鈕,在你的項目路徑中找到WindowsApplication.exe.mnifest並打開他。
3.在自定義資源類型對話框中我們輸入RT_MANIFEST然後點擊確定。
4.保存所有文件讓我們回到先前的資源來瀏覽樹。我們現在可以看到一個RT_MANIFEST的節點。
5.點擊選中他下面那個新加的資源文件,通常的名字是101。在屬性窗口裏修改他的ID值爲1,再一次保存你的應用程序。
6.關閉你打開的資源瀏覽窗口回到命令行提示符下,輸入下面的命令:
sn –R WindowsApplication1.exe ../../KeyFile.snk
執行後會輸出一些版本信息,最後顯示:
Assembly ‘WindowsApplication1.exe’ successfully re-signed
運行你的.NET應用程序你就會看到Windows XP樣式了。
請記住把那些帶有FlatStyle屬性的控件設置爲FlatStyle.System,同時在編譯你的程序後加入manifest資源就象上面的樣板文件。當這些都做好了以後剩下的就是完成對程序集的簽名。如果你想要測試你的應用程序或者你有權限對他進行簽名,你可以通過下面的命令關閉對程序集的驗證:
sn.exe –Vr WindowsApplication1.exe
立即行動,爲你的應用程序加上Xp樣式,使你的產品更有特點。這樣做不會花很多時間但是效果是顯而易見的。
請記住把那些帶有FlatStyle屬性的控件設置爲FlatStyle.System,同時在編譯你的程序後加入manifest資源就象上面的樣板文件。當這些都做好了以後剩下的就是完成對程序集的簽名。如果你想要測試你的應用程序或者你有權限對他進行簽名,你可以通過下面的命令關閉對程序集的驗證:
sn.exe –Vr WindowsApplication1.exe
立即行動,爲你的應用程序加上Xp樣式,使你的產品更有特點。這樣做不會花很多時間但是效果是顯而易見的。