網路上討論程式實現XP風ge已經很久了,但對於VB程式實現XP風ge,卻終沒有一個完美的解決方案。筆者透過N個日夜的刻苦鑽研終於揭開其中奧秘。以下分為三個面向與大家共享之。
點擊下載原始碼文件
一.用manifest檔實現XP風ge
正常情況下,在Windows XP系統中,用VB6開發的應用程式只有視窗標題條具備XP風ge,窗體上的按鈕、文字方塊等控制項仍顯示Windows傳統風ge。如圖1所示:
透過查閱MSDN裡的Visual Style章節知道,Windows XP透過Comctl32.dll(版本6)來載入具備XP風ge的元件,應用程式則透過一個XML資源檔案來通知系統來做這些。 XML檔案的內容如下:
<?xml version=1.0 encoding=UTF-8 standalone=yes?>
<assembly xmlns=urn:schemas-microsoft-com:asm.v1 manifestVersion=1.0>
<assemblyIdentity
name=XP style manifest
processorArchitecture=x86
version=1.0.0.0
type=win32/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type=win32
name=Microsoft.Windows.Common-Controls
version=6.0.0.0
processorArchitecture=x86
publicKeyToken=6595b64144ccf1df
language=*
/>
</dependentAssembly>
</dependency>
</assembly>
假設你最後編譯的程式名稱是abc.exe,工作目錄是d:/vbxp。複製上述XML內容並儲存為文字檔。然後將該檔案改名為abc.exe.manifest(注意.txt副檔名要去掉)。在VB程式中,我們要在所有窗體載入之前呼叫InitCommonControlsEx函數從comctl32.dll(版本6)中對元件類別進行初始化。 API函數InitCommonControlsEx及相關常數、資料類型的宣告如下:
Private Declare Function InitCommonControlsEx Lib comctl32.dll _
(iccex As tagInitCommonControlsEx) As Boolean
Private Type tagInitCommonControlsEx
lngSize As Long
lngICC As Long
End Type
Private Const ICC_USEREX_CLASSES = &H200
這裡我們寫一個函數封裝初始化操作:
Public Function InitCommonControlsVB() As Boolean
On Error Resume Next
Dim iccex As tagInitCommonControlsEx
With iccex
.lngSize = LenB(iccex)
.lngICC = ICC_USEREX_CLASSES
End With
InitCommonControlsEx iccex
InitCommonControlsVB = (Err.Number = 0)
On Error Goto 0
End Function
注意初始化動作必須在所有視窗載入前完成,所以要把相關語句放到Sub Main()中,並設定工程從Sub Main()啟動。程式碼如下:
Sub Main()
InitCommonControlsVB
Form1.Show
End Sub
至此,你編譯後的abc.exe將具備XP風ge,如圖2: