(转载)使用 Windows XP 的外观风格

来源:互联网 发布:dev c 编程 编辑:程序博客网 时间:2024/04/25 05:33

本文只是初步的文档,如有更改,恕不另行通知。

概要:本文档说明了如何使用 Microsoft Windows XP 来完成将外观风格应用于应用程序时必需执行的常见任务。

目录

简介

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

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

  • 计算器

     
  • FreeCell

     
  • 扫雷

     
  • 记事本

     
  • 纸牌

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

  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

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

  • Microsoft Management Console (Mmc.exe)

     
  • Windows Shell

     
  • Microsoft® Visual Studio®

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

  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 以获得刚加载的外观风格的主题句柄。

       
    • 此代码示例说明了这两种调用。
      case WM_THEMECHANGED:    CloseThemeData (hTheme);    hTheme = OpenThemeData (hwnd, L"MyClassName");    
  6. 控件在接收到 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,还必须传入该控件的窗口句柄,并为 pszSubAppNamepszSubIdList 参数传入空字符串。通过调用带有空字符串的 SetWindowTheme 函数,可以使控件不呈现外观风格。以下代码片断显示了如何创建按钮控件,然后调用 SetWindowTheme 函数来删除按钮的外观风格。

HWND hwndButton;hwndButton = CreateWindow (TEXT ("按钮"), …);if (hwndButton){   SetWindowTheme (hwndButton, TEXT (" "), TEXT (" "));}

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

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

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

  • 基本方法是使用系统标准颜色。大多数系统标准颜色都在应用外观风格文件时设置。

     
  • 您可以使用其它控件的部件,并分别呈现每个部件。例如,对于由网格组成的日历控件,您可以将网格所形成的每个正方形当作工具栏按钮。执行以下步骤将正方形编程为工具栏按钮。

    调用 OpenThemeData,如下所示:

    OpenThemeData (hwnd, "Toolbar");

    使用返回的主题句柄来呈现日历上的每个正方形。

  • 要组合和匹配控件部件,可以对给定控件多次调用 OpenThemeData 并使用相应的主题句柄来绘制不同的部件。但是,在某些外观风格中,有些部件可能与其它部件不兼容。

     
  • 有些专用的应用程序需要在控件级以上与 Windows XP 外观匹配,它们就可能需要检测当前加载的外观风格,并设计与外观匹配的自定义呈现。对于提供外观风格体系结构的应用程序而言,这是很有用的。

将外观风格用于 HTML 内容

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

  • 与 HTML 内容相关的外观风格仅应用于固有的 HTML 控件,如按钮、滚动条和选择控件。Windows XP 的外观风格将自动应用于 HTML 页面上的控件。如果不想将外观风格应用于页面,请使用属性设置为 NO 的 META 标记。在下面的一节中说明了此 META 标记。

     
  • 不会对修改了层叠样式表 (CSS)(如背景或边框)的 HTML 页面应用外观风格。它们将显示指定的 CSS 属性。

     
  • 大多数 CSS 属性在被指定为内容的一部分时,都可以应用于已应用外观风格的元素。

     
  • 您必须在页面的 <head> 部分中添加元标记。您只需将该标记添加一次,外观风格就能将其应用于所有页面内容。它也将应用于打包为 HTA 的内容。元标记必须如下:
    <META HTTP-EQUIV="MSThemeCompatible" CONTENT="Yes">
  • 注意,外观风格可能会更改内容的布局。此外,在设置固有 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 不可重新分发。

总结

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