[转] 使用 Windows XP 的外观风格

发布时间:2010-2-11 15:49
分类名称:windows


原文链接:blog.csdn.net/whchen/archive/2006/08/21/1101237.aspx
英文链接:msdn.microsoft.com/en-us/library/ms997646.aspx

简介

通 过使用 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

下面是一些未使用第三方扩展的应用程序示例。

要创建声明并使您的应用程序能够使用外观风格,请执行以下步骤:

  1. 链接到 ComCtl32.lib 并调用 InitCommonControls(请参阅 MSDN Library 中的 Platform SDK 文档)。
  2. 将名为 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>

  3. 将声明添加到应用程序的资源文件中,如下所示:

    CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourApp.exe.manifest"

注意:如果将前一项添加到资源中,则必须在一行中对其进行格式设置。或者,您可以将 XML 声明文件放置在与应用程序的可执行文件相同的目录中。操作系统将首先从文件系统加载声明,然后检查可执行文件的资源部分。文件系统版本优先。

在使用扩展、插件或进程内运行的 DLL 的应用程序中使用 ComCtl32 版本 6

下面是一些使用扩展的应用程序的示例。

要创建声明并使您的应用程序能够使用外观风格,请执行以下步骤:

  1. 使用 Windows XP Beta 2 SDK 或更高版本。
  2. 包括常用控件标题文件,如下所示:

    #include "commctrl.h"

  3. 定义编译器变量预处理程序定义,如下所示:

    #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>

  4. 将声明添加到应用程序的资源文件中,如下所示:

    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

要创建声明并使您的应用程序能够使用外观风格,请执行以下步骤:

  1. 链接到 ComCtl32.lib 并调用 InitCommonControls
  2. 将名为 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>

  3. 将声明添加到应用程序的资源文件中,如下所示:

    CONTROL_PANEL_RESOURCE_ID RT_MANIFEST "YourCpl.manifest"

注意:编写完控制面板应用程序后,请将其放置在相应的类别中。现在,控制面板支持控制面板应用程序的分类。也就是说,可以为控制面板应用程序分配标识符并将其分为若干个任务区域,如“添加或删除程序”、“外观和主题”、“日期、时间、语言和区域选项”。

将外观风格用于自定义控件

标 题文件 Uxtheme.h 中定义了在向控件添加外观风格的步骤中以及在相应的代码示例中所引用的 UxTheme API。Platform SDK 中对该 API 的各元素进行了说明。本节将说明将外观风格应用于控件的步骤,并提供一个绘图代码示例以及有关绘制控件的技巧。

要使控件能够应用外观风格,请执行以下步骤:

  1. 调用 OpenThemeData 并将要应用外观风格的控件的 hwnd 传递给说明控件类型的类列表。Tmschema.h 中定义了各个类。OpenThemeData 返回一个 HTHEME 句柄,但是,如果外观风格管理器被禁用或当前的外观风格没有为给定控件提供特定的信息,该函数将返回 NULL。如果返回值是 NULL,则使用非外观风格的绘图函数。
  2. 要绘制控件,请调用 DrawThemeBackground 并传递以下内容:
    • OpenThemeData 所返回的主题句柄 HDC,它用于呈现控件。
    • 部件标识符,用于说明要呈现的控件部件。有关控件的部件和状态的信息,请参见“主题部件和状态”。
    • 状态标识符,用于说明部件的当前状态。
    • 指向 RECT 结构的指针,该结构包含将呈现控件的矩形的坐标。
  3. 有些部件可以是半透明的。要确定部件的透明度,可以使用主题句柄、控件部件和控件状态调用 IsThemeBackgroundPartiallyTransparent
  4. 如果控件绘制的是文本,请将文本放置于控件的内容矩形中并选择字体。
    • 要确定内容矩形的位置,请调用 GetThemeBackgroundContentRect
    • 将所需字体添加到设备上下文 (DC) 中,然后调用 DrawThemeText。该函数将启用外观效果,如一些控件中的阴影文本。
  5. 控件在接收到 WM_THEMECHANGED 消息后,应执行以下操作:
    • 调用 CloseThemeData 以关闭现有主题句柄。
    • 调用 OpenThemeData 以获得刚加载的外观风格的主题句柄。
    • 此代码示例说明了这两种调用。
      de>case WM_THEMECHANGED:
      CloseThemeData (hTheme);
      hTheme = OpenThemeData (hwnd, L"MyClassName");
      de>
  6. 控件在接收到 WM_DESTROY 消息后,将调用 CloseThemeData 以释放在调用 OpenThemeData 时返回的主题句柄。

绘图代码示例

下面的代码示例说明了如何绘制按钮控件。

de>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
{
// 绘制控件时不使用外观风格。
}
}
de>

使自行绘制的控件能够使用外观风格

在 Windows XP 中,控件不再仅仅由线条和填充色组成。现在,它们包括可以随控件状态而变化的丰富纹理和图案。这意味着您不能使用现有的编程元素来说明那些与已应用外观风 格的控件具有相同外观的自行绘制控件。如果您的代码中已包含自行绘制控件,则可以进行以下选择。

使控件在具有外观风格的对话框或窗口中不显示外观风格

在某些情况下,应用程序具有不应该使用外观风格的自定义绘制控件(即使窗口中的其它控件已应用外观风格)。如果要将任何自定义绘制的控件标记为无外观风格,必须调用 SetWindowTheme,还必须传入该控件的窗口句柄,并为 pszSubAppNamepszSubIdList 参数传入空字符串。通过调用带有空字符串的 SetWindowTheme 函数,可以使控件不呈现外观风格。以下代码片断显示了如何创建按钮控件,然后调用 SetWindowTheme 函数来删除按钮的外观风格。

de>HWND hwndButton;

hwndButton = CreateWindow (TEXT ("按钮"), ...);
if (hwndButton)
{
SetWindowTheme (hwndButton, TEXT (" "), TEXT (" "));
}
de>

注意:如果您决定在运行时将控件更改为外观风格控件,可以调用 SetWindowTheme,但将 NULL 传递给两个字符串参数。

使用 UxTheme 管理程序呈现其部件不具有外观风格的控件

如果您的控件不属于常用控件,但希望该控件在安装有外观风格文件的计算机上具有适当的外观,则可以采用以下方法之一。

将外观风格用于 HTML 内容

很 多应用程序是用 HTML 编写并作为 HTML 应用程序 (HTA) 或 Win32 应用程序来部署的。这些应用程序使用的是 HTML 或在它们的 UI 元素中托管 WebObject。当在 Windows XP 上运行时,这些应用程序将与运行在同一操作系统上基于 Win32 的应用程序具有一致的外观。将外观风格应用于 HTML 内容时,需要考虑以下事项:

使 UxTheme 管理程序忽略顶层窗口

为了避免将新的外观风格应用于顶层窗口,请考虑以下因素:

使用 32 位抗失真图标

Windows XP 图像列表是用于某些控件(如列表视图控件)的图像集,它支持使用 32 位抗失真图标和位图。颜色值使用 24 位,而 8 位用作图标上的 alpha 通道。要创建可以处理 32 位/像素 (bpp) 图像的图像列表,请调用 ImageList_Create 函数,并传递 ILC_COLOR32 标志。

下图说明了图标格式尚未更改,但创建这些图标的方式已经改变。



[转] 使用 Windows XP 的外观风格 - Dsliu - Dspace

图标格式

要正确创建 32 位图标,请执行以下步骤:


[转] 使用 Windows XP 的外观风格 - Dsliu - Dspace

同一图标的多个图像

注意:您可以使用第三方工具生成包含 Alpha 通道的图标文件和位图。

使您的应用程序可同时在 Windows XP 和 Windows 的早期版本上正常运行

Windows XP 外观风格体系结构中的大部分都是为了使您的产品仍能在不支持更改控件外观的旧版 Windows 上正常运行。为了使应用程序能在多个操作系统上正常运行,请注意以下事项:

总结

本文档说明了将外观风格应用于应用程序时必须执行的任务。它没有包括需要执行的所有任务,而是讨论了一些最常见任务。