目錄
- 簡介
- ComCtl32.dll 版本 6
- 外觀風格任務
- 在未使用第三方擴充的應用程式中使用 ComCtl32.dll 版本 6
- 在使用擴充、外掛程式或進程內啟動並執行 DLL 的應用程式中使用 ComCtl32 版本 6
- 在控制台中或在通過 RunDll32.exe 啟動並執行 DLL 中使用 ComCtl32 版本 6
- 將外觀風格用於自訂控制項
- 使自行繪製的控制項能夠使用外觀風格
- 使控制項在具有外觀風格的對話方塊或視窗中不顯示外觀風格
- 使用 UxTheme 管理程式呈現其組件不具有外觀風格的控制項
- 將外觀風格用於 HTML 內容
- 使 UxTheme 管理程式忽略頂層視窗
- 使用 32 位抗失真表徵圖
- 使您的應用程式可同時在 Windows XP 和 Windows 的早期版本上正常運行
- 總結
簡介
通過使用 Microsoft Windows XP,您現在可以定義控制項和視窗的外觀風格,例如簡單的顏色以及紋理和形狀。您可以控制控制項中的每個定義組件,也可以控制視窗中非用戶端(架構和標題)區 域的每個組件。之後,使用者可以使用 Windows 控制台中的“外觀”選項卡在傳統外觀風格和其它可用風格之間進行切換。
Windows XP 版本提供外觀風格。通過使用助手庫和應用編程介面 (API),您無需更改過多代碼即可在您的應用程式中使用 Windows XP 的外觀風格。有關詳細資料,請參閱 MSDN Library 中的 Platform SDK 文檔。
ComCtl32.dll 版本 6
Windows XP 作業系統上啟動並執行所有應用程式都有一個非用戶端地區,其中包括視窗架構和非用戶端捲軸。預設情況下,外觀風格將應用於非用戶端地區。這意味著非用戶端區 域的外觀由當前安裝的外觀風格指定。要將外觀風格應用於用戶端地區中的常用控制項,必須使用 ComCtl32.dll 版本 6 或更高版本。與 ComCtl32.dll 的早期版本不同,ComCtl32.dll 版本 6 不可重新分發。要使用動態連結程式庫 (DLL) 的版本 6,唯一途徑是使用包含它的作業系統。Windows XP 同時提供版本 5 和版本 6。ComCtl32.dll 版本 6 中包含使用者控制項和常用控制項。預設情況下,各種應用程式使用 User32.dll 中定義的使用者控制項和 ComCtl32.dll 版本 5 中定義的常用控制項。
如果要讓您的應用程式使用外觀風格,必須添加應用程式聲明,指出如果 ComCtl32.dll 版本 6 可用,則應該使用它。版本 6 包括一些新控制項和其它控制項的新選項,但是,最大的變化是支援對控制項在視窗中的外觀變更。
外觀風格任務
要將外觀風格添加到您的控制項,可能需要執行以下一些任務。
在未使用第三方擴充的應用程式中使用 ComCtl32.dll 版本 6
下面是一些未使用第三方擴充的應用程式樣本。
要建立聲明並使您的應用程式能夠使用外觀風格,請執行以下步驟:
- 連結到 ComCtl32.lib 並調用 InitCommonControls(請參閱 MSDN Library 中的 Platform SDK 文檔)。
- 將名為 YourApp.exe.manifest 的檔案添加到具有以下 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="CompanyName.ProductName.YourApp"
type="win32"
/>
<description>此處是您的應用程式說明。</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
- 將聲明添加到應用程式的資源檔中,如下所示:
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourApp.exe.manifest"
注意:如果將前一項添加到資源中,則必須在一行中對其進行格式設定。或者,您可以將 XML 聲明檔案放置在與應用程式的可執行檔相同的目錄中。作業系統將首先從檔案系統載入聲明,然後檢查可執行檔的資源部分。檔案系統版本優先。
在使用擴充、外掛程式或進程內啟動並執行 DLL 的應用程式中使用 ComCtl32 版本 6
下面是一些使用擴充的應用程式的樣本。
- Microsoft Management Console (Mmc.exe)
- Windows Shell
- Microsoft Visual Studio
要建立聲明並使您的應用程式能夠使用外觀風格,請執行以下步驟:
- 使用 Windows XP Beta 2 SDK 或更高版本。
- 包括常用控制項標題檔案,如下所示:
#include "commctrl.h"
- 定義編譯器變數預先處理程式定義,如下所示:
#define SIDEBYSIDE_COMMONCONTROLS 1
將名為 YourApp.manifest 檔案添加到具有以下 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="CompanyName.ProductName.YourApp"
type="win32"
/>
<description>此處是您的應用程式說明。</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
- 將聲明添加到應用程式的資源檔中,如下所示:
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourApp.manifest"
Winuser.rh 包括以下定義:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define CONTROL_PANEL_RESOURCE_ID 123
#define RT_MANIFEST 24
在控制台中或在通過 RunDll32.exe 啟動並執行 DLL 中使用 ComCtl32 版本 6
要建立聲明並使您的應用程式能夠使用外觀風格,請執行以下步驟:
- 連結到 ComCtl32.lib 並調用 InitCommonControls。
- 將名為 YourApp.cpl.manifest 檔案添加到具有以下 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="CompanyName.ProductName.YourApp"
type="win32"
/>
<description>此處是您的應用程式說明。</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
- 將聲明添加到應用程式的資源檔中,如下所示:
CONTROL_PANEL_RESOURCE_ID RT_MANIFEST "YourCpl.manifest"
注意:編寫完控制台應用程式後,請將其放置在相應的類別中。現在,控制台支援控制台應用程式的分類。也就是說,可以為控制台應用程式分配標識符並將其分為若干個工作區域,如“添加或刪除程式”、“外觀和主題”、“日期、時間、語言和地區選項”。
將外觀風格用於自訂控制項
標題檔案 Uxtheme.h 中定義了在向控制項添加外觀風格的步驟中以及在相應的程式碼範例中所引用的 UxTheme API。Platform SDK 中對該 API 的各元素進行了說明。本節將說明將外觀風格應用於控制項的步驟,並提供一個繪圖程式碼範例以及有關繪製控制項的技巧。
要使控制項能夠套用面板風格,請執行以下步驟:
- 調用 OpenThemeData 並將要套用面板風格的控制項的 hwnd 傳遞給說明控制項類型的類列表。Tmschema.h 中定義了各個類。OpenThemeData 返回一個 HTHEME 控制代碼,但是,如果外觀風格管理器被禁用或當前的外觀風格沒有為給定控制項提供特定的資訊,該函數將返回 NULL。如果傳回值是 NULL,則使用非外觀風格的繪圖函數。
- 要繪製控制項,請調用 DrawThemeBackground 並傳遞以下內容:
- OpenThemeData 所返回的主題控制代碼 HDC,它用於呈現控制項。
- 組件標識符,用於說明要呈現的控制項組件。有關控制項的組件和狀態的資訊,請參見“主題組件和狀態”。
- 狀態標識符,用於說明組件的目前狀態。
- 指向 RECT 結構的指標,該結構包含將呈現控制項的矩形的座標。
- 有些組件可以是半透明的。要確定組件的透明度,可以使用主題控制代碼、控制項組件和控制項狀態調用 IsThemeBackgroundPartiallyTransparent。
- 如果控制項繪製的是文本,請將文本放置於控制項的內容矩形中並選擇字型。
- 要確定內容矩形的位置,請調用 GetThemeBackgroundContentRect。
- 將所需字型添加到裝置上下文 (DC) 中,然後調用 DrawThemeText。該函數將啟用外觀效果,如一些控制項中的陰影文本。
- 控制項在接收到 WM_THEMECHANGED 訊息後,應執行以下操作:
- 控制項在接收到 WM_DESTROY 訊息後,將調用 CloseThemeData 以釋放在調用 OpenThemeData 時返回的主題控制代碼。
繪圖程式碼範例
下面的程式碼範例說明了如何繪製按鈕控制項。
HTHEME hTheme = NULL;
hTheme = OpenThemeData(hwndButton, "Button");
...
DrawMyControl(hDC, hwndButton, hTheme, iState);
...
if (hTheme)
{
CloseTheme(hTheme);
}
void DrawMyControl(HDC hDC, HWND hwndButton, HTHEME hTheme, int iState)
{
RECT rc, rcContent;
TCHAR szButtonText[255];
HRESULT hr;
GetWindowRect(hwndButton, &rc);
GetWindowText(hwndButton, szButtonText,
ARRAYSIZE(szButtonText));
if (hTheme)
{
hr = DrawThemeBackground(hTheme, hDC, BP_BUTTON,
iState, &rc, 0);
//務必檢查產生的程式碼。
hr = GetThemeBackgroundContentRect(hTheme,
BP_BUTTON, iState, &rc, &rcContent);
hr = DrawThemeText(hTheme, hDC, BP_BUTTON, iState,
szButtonText, lstrlen(szButtonText),
DT_CENTER | DT_VCENTER | DT_SINGLELINE,
0, &rcContent);
}
else
{
// 繪製控制項時不使用外觀風格。
}
}
使自行繪製的控制項能夠使用外觀風格
在 Windows XP 中,控制項不再僅僅由線條和填充色組成。現在,它們包括可以隨控制項狀態而變化的豐富紋理和圖案。這意味著您不能使用現有的編程元素來說明那些與已套用面板風 格的控制項具有相同外觀的自行繪製控制項。如果您的代碼中已包含自行繪製控制項,則可以進行以下選擇。
- 您可以調用 SetWindowTheme 來關閉控制項的主題。
SetWindowTheme (hwndButton, TEXT (" "), TEXT (" "));
控制項的呈現方式與在 Windows 早期版本中相同。
- 您可以在控制項中繼續使用自行繪製方法,但有些屬性將被忽略。例如,如果更改按鈕的背景顏色,那麼按鈕將被繪製成已套用面板風格的按鈕,但背景顏色並不是指定的顏色。但是,如果更改字型,則將使用指定的字型繪製該按鈕。
使控制項在具有外觀風格的對話方塊或視窗中不顯示外觀風格
在某些情況下,應用程式具有不應該使用外觀風格的自訂繪製控制項(即使視窗中的其它控制項已套用面板風格)。如果要將任何自訂繪製的控制項標記為無外觀風格,必須調用 SetWindowTheme,還必須傳入該控制項的視窗控制代碼,並為 pszSubAppName 和 pszSubIdList 參數傳入Null 字元串。通過調用帶有Null 字元串的 SetWindowTheme 函數,可以使控制項不呈現外觀風格。以下代碼片斷顯示了如何建立按鈕控制項,然後調用 SetWindowTheme 函數來刪除按鈕的外觀風格。
HWND hwndButton;
hwndButton = CreateWindow (TEXT ("按鈕"), ...);
if (hwndButton)
{
SetWindowTheme (hwndButton, TEXT (" "), TEXT (" "));
}
注意:如果您決定在運行時將控制項更改為外觀風格控制項,可以調用 SetWindowTheme,但將 NULL 傳遞給兩個字串參數。
使用 UxTheme 管理程式呈現其組件不具有外觀風格的控制項
如果您的控制項不屬於常用控制項,但希望該控制項在安裝有外觀風格檔案的電腦上具有適當的外觀,則可以採用以下方法之一。
將外觀風格用於 HTML 內容
很多應用程式是用 HTML 編寫並作為 HTML 應用程式 (HTA) 或 Win32 應用程式來部署的。這些應用程式使用的是 HTML 或在它們的 UI 元素中託管 WebObject。當在 Windows XP 上運行時,這些應用程式將與運行在同一作業系統上基於 Win32 的應用程式具有一致的外觀。將外觀風格應用於 HTML 內容時,需要考慮以下事項:
使 UxTheme 管理程式忽略頂層視窗
為了避免將新的外觀風格應用於頂層視窗,請考慮以下因素:
- 如果視窗已應用一個地區,UxTheme Manager 就將假定該地區是一個專用視窗,並且該視窗在其整個生存期中將不使用外觀風格。即使父視窗並沒有使用外觀風格,與非外觀風格的頂層視窗相關聯的子視窗仍可能套用面板風格。
- 如果您將某個地區應用於頂層視窗,隨後又將其刪除,那麼外觀風格將不會自動應用於該視窗。要將外觀風格應用於該視窗,您必須建立一個新視窗。
- 如果要禁止應用程式中所有頂層視窗使用外觀風格,請調用 SetThemeAppProperties,但不傳遞 STAP_ALLOW_NONCLIENT 標誌。
- 如果應用程式未調用 SetThemeAppProperties,則假定的標誌值為 STAP_ALLOW_NONCLIENT | STAP_ALLOW_CONTROLS | STAP_ALLOW_WEBCONTENT。假定值將使非用戶端地區、控制項以及 Web 內容套用面板風格。
使用 32 位抗失真表徵圖
Windows XP 映像列表是用於某些控制項(如列表視圖控制項)的映像集,它支援使用 32 位抗失真表徵圖和位元影像。顏色值使用 24 位,而 8 位用作表徵圖上的 Alpha 色板。要建立可以處理 32 位/像素 (bpp) 映像的映像列表,請調用 ImageList_Create 函數,並傳遞 ILC_COLOR32 標誌。
說明了表徵圖格式尚未更改,但建立這些表徵圖的方式已經改變。
表徵圖格式
要正確建立 32 位元影像標,請執行以下步驟:
同一表徵圖的多個映像
- 在中,前三個映像為 16 色模式,用於安全模式。
- 接下來的三個表徵圖用於 Windows XP 256 色模式。
- 最後三個表徵圖具有 Alpha 通道,僅能用於以 24 位或更高位顏色啟動並執行 Windows XP 或更高版本的作業系統。
- 在表徵圖格式中,這些映像的排列順序比較重要。如果順序不正確,低版本 Windows 在抽取這些表徵圖時可能會出錯。錯誤地抽取表徵圖會導致記憶體崩潰和呈現不正常。
- Windows 早期版本具有 10 個表徵圖的資源限制,而 Windows XP 卻支援上千個表徵圖資源。
注意:您可以使用第三方工具產生包含 Alpha 通道的表徵圖檔案和位元影像。
使您的應用程式可同時在 Windows XP 和 Windows 的早期版本上正常運行
Windows XP 外觀風格體繫結構中的大部分都是為了使您的產品仍能在不支援更改控制面板的舊版 Windows 上正常運行。為了使應用程式能在多個作業系統上正常運行,請注意以下事項:
- 在舊版本作業系統中安裝應用程式的聲明將不會影響控制項的顯示。
- 您必須測試您的應用程式,以確保先檢查目前的版本而不依賴於 ComCtl32.dll 版本 6 的功能。
- 不要直接連結到 UxTheme.lib。如果您使用 UxTheme API 來向自訂控制項添加外觀風格,請根據需要載入庫。
- 如果外觀風格無法達到預期效果,則為執行個體編寫錯誤處理代碼。
- 如果您使用的是 ComCtl32.dll 版本 6 中的功能(如平鋪視圖或連結控制項),則必須處理無法在使用者電腦上使用這些控制項的情況。ComCtl32.dll 版本 6 不可重新分發。
總結
本文檔說明了將外觀風格應用於應用程式時必須執行的任務。它沒有包括需要執行的所有任務,而是討論了一些最常見任務。