Delphi 完全時尚手冊之 Visual Style 篇---使非標準 Win32 控制元件或自畫控制元件也具有 Windows XP 的介面風格 (轉)

amyz發表於2007-08-14
Delphi 完全時尚手冊之 Visual Style 篇---使非標準 Win32 控制元件或自畫控制元件也具有 Windows XP 的介面風格 (轉)[@more@] 完全時尚手冊之 Visual Style 篇
---使非標準 或自畫控制元件也具有 XP 的介面風格

 這裡先說說兩個概念:Theme(主題)和 Visual Style 。Theme 最早出現在 Plus! for Windows 95 中,是 Windows 中 Wallpaper、Cursors、Fonts、Sounds 、Icons 等的設定值集合。Visual Style 在 Windows 中才被引入,Visual Style 規定了 Contorls 的外觀,另外還包括使用這些外觀的一套 。使用 Visual Style 必須要 ComCtl32.dll 6,而 ComCtl32.dll 6 是不能被分發到以前版本的 Windows 中的,所以只能在 Windows XP 下使用 Visual Style。

 Delphi 7 (後面簡稱 7 吧)對 Visual Style 提供了較好的支援。首先 7 將那個 Menifest 封裝成了 VCL - TXPMenifest,另外增加了 UxTheme.pas 單元,裡面是對 Visual Style 的一套 API 及其結構、常數等的引用宣告(大概有 47 個API ),更重要的是 7 還增加一個 Themes.pas 單元,裡面是對這套 API 的更進一步的簡化和封裝,7 下的 Win32 控制元件對 Visual Style 的支援較 Delphi 6有了很大改觀,就是這個單元的功勞。

 一般來說要使 7 下編譯的在 Windows XP 具有 Visual Style ,只需在主窗體上放入 VCL - TXPMenifest 即可,但對於一些非標準或是自畫的控制元件,還是經典的介面。這裡就說一下如何用 Themes.pas 中提供的方法使這些控制元件具有 Visual Style 。

 Themes.pas 中只有一個類:TThemeServices 。這個類有一個重要的屬性: ThemesEnabled (Boolean 型別),就是判斷在當前程式能不能使用 Visual Style ,這個屬性只有在程式使用了 TXPMenifest 並且在 Windows XP 下執行並且使用了 Windows XP 的主題(即桌面主題不是 Windows 經典)才為 True ,由於程式要執行在以前版本的 Windows 下,所以你的程式也得提供這個屬性為 False 時的處理過程(一般就是原有的處理過程)。還要提一下這個類封裝的幾個重要函式:DrawEdge 用來畫控制元件邊界的,DrawElement 用來畫整個介面的,DrawText 用來寫字的。這個類還處理了 WM_THEMECHANGED 訊息,這樣當我們在改變桌面主題後,程式會自動調整外觀。再說一下我們最常用到的一個函式(多型函式):GetElementDetails ,這個函式的返回值在上面的幾個 DrawXXX 函式中要用到,這個函式的輸入值是 24 個列舉型別中的元素,這 24 個列舉型別在 Themes.pas 單元開頭定義(從第二個 TThemeutton 開始直到 TThemedWindow)。最後,我們不去直接使用這個類,在 Themes.pas 單元中有一函式:

function ThemeServices: TThemeServices;


返回值就是這個類,所以我們直接使用這個方法,7 的 VCL 裡都是這樣做。

 好,下面就來個簡單的例子。Delphi 的 TPanel 控制元件不是標準控制元件,我們就來在它上面實現一下 Visual Style 。在 Delphi 7 中新建一工程,在主窗體上放入 TXPMenifest ,在 Unit1 單元引用 Themes 單元,在

TForm1 = class(TForm)


前面加入下程式碼(主要是過載 TCustomPanel 的 Paint 方法):

TVSPanel = class(TCustomPanel) private // protected procedure Paint; overr; public // end;


過載的 Paint 方法實現如下:

procedure TVSPanel.Paint; var Details: TThemedElementDetails; begin inherited; if ThemeServices.ThemesEnabled then begin Details := ThemeServices.GetElementDetails(tbPushButtonHot); {這裡畫個按鈕處於 Hot 狀態下的樣子} PerformEraseBackground(Self, Canvas.Handle); {擦除畫按鈕時的背景} ThemeServices.DrawElement(Canvas.Handle, Details, ClientRect); ThemeServices.DrawText(Canvas.Handle, Details, Caption, ClientRect, DT_EXPANDTABS or DT_VCENTER or DT_CENTER or DT_SINGLELINE, 0); end; end;


TCustomPanel 的改動完成,再就是在主窗體的 Create 事件中例項化 TVSPanel ,程式碼如下:

procedure TForm1.FormCreate(Sender: T); var APanel: TVSPanel; begin APanel := TVSPanel.Create(Application); APanel.Left := 100; APanel.Top := 100; APanel.Width := 200; APanel.Height := 30; APanel.Caption := '具有 Button 風格的 Panel'; APanel.Parent := Self; end;


 好了,執行看看 Visual Style 效果是不是出來了。我的程式裡用 THintWindow 做了個浮動視窗並且加上了 Visual Style ,效果還不錯,如果再細緻點的話,就做出和 Windows XP 下拼音輸入法那個浮動條完全相同的介面了。

 另外,還有幾個重要的東西沒有提及,比如 Part 和 State ,大家可以查 MSDN ,在 User Interface Design and Development Windows Shell Refrence Visual Styles Refrence 裡,也可 E 與我討論:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-956498/,如需轉載,請註明出處,否則將追究法律責任。

相關文章