使用 HTHEME 包装器为 OWNERDRAW 控件添加 XP 视觉样式支持






4.86/5 (4投票s)
2002 年 1 月 30 日
3分钟阅读

160617

1016
一个用于使用 Windows XP 中可用的视觉样式 API 的包装类。
引言
这是 Windows XP 中提供的 Visual Styles API 中使用的 HTHEME
句柄的包装类。本文和提供的代码在很大程度上基于 在 OWNERDRAW 控件中添加 XP 视觉样式支持,作者为 David Yuheng Zhao。 为了理解本文和提供的代码,我强烈建议您阅读该文章。
提供的类基于前面提到的文章中描述的 CVisualStylesXP
类,实际上代码的几个部分是直接复制的,但进行了一些主要的概念性更改。 uxtheme.dll 的句柄不再是 CVisualStylesXP
类的普通成员,而是在 CXPTheme
中设置为 static
,从而每个应用程序只加载一次。 此外,由 GetProcAddress
返回的函数指针缓存在 static
函数指针中,然后在后续调用中使用。 在 DLL 不可用的情况下,会将提供合理响应的特殊失败成员方法的地址分配给这些 static
函数指针。 这可以实现高度优化的执行。
对于此类用户而言,更显着的差异是 CXPTheme
包装了 HTHEME
句柄。 这为使用 API 提供了更面向对象的方法。 除非有特殊需要,否则用户永远不会直接与 HTHEME
句柄交互。 相反,句柄保留在成员变量中,并在必要时在内部应用。 句柄在类析构函数中关闭。 该类提供了多个构造函数和重载运算符,以方便使用。
与 HTHEME
没有直接关系的 API 函数被创建为 static
成员方法,不需要类的实例。 此外,还添加了 static
成员方法 IsAvailable
,用于专门检查当前平台是否支持主题。 在大多数情况下,使用 IsAppThemed
API 函数就足够了,因为相应的特殊失败方法会在不提供主题的平台上返回 FALSE
,表示“旧式”绘图。
如何使用
该类非常易于使用。 首先,您需要在stdafx.h中包含标头,并将CPP文件添加到项目中。
#include "XPTheme.h"
然后,您可以在需要的地方创建一个本地 CXPTheme
变量,或者将其添加为控件的类成员。
CXPTheme theme(GetSafeHwnd(), L"TOOLBAR");
theme.DrawBackground(pDC->GetSafeHdc(), TP_BUTTON, TS_CHECKED, &rc, 0);
// the handle is closed when the variable goes out of scope.
为了使您的应用程序在所有 Windows 版本下都能工作,您应该这样做
#ifdef _XPTHEME_H_
if (CXPTheme::IsAppThemed())
{
CXPTheme theme(GetSafeHwnd(), L"TOOLBAR");
theme.DrawBackground(pDC->GetSafeHdc(), TP_BUTTON, TS_CHECKED, &rc, 0);
}
else
{
#endif
pDC->DrawEdge(....);
#ifdef _XPTHEME_H_
}
#endif
使用此类的首选方式可能是使其成为在控件构造函数中初始化的控件成员变量。 删除控件后,CXPTheme
变量也将被删除,并且句柄会安全关闭。 控件应处理新的 WM_THEMECHANGED
消息,并使用 Close
和 Open
成员方法关闭并重新打开主题。 实际上,可以单独使用 Open
方法,因为在打开新句柄之前,会自动关闭已打开的句柄。
case WM_THEMECHANGED:
m_theme.Close();
m_theme.Open(GetSafeHwnd(), L"TOOLBAR");
break;
除了从 Platform SDK 中提取的三个头文件外,下载还包括类本身。 这些对于在没有最新 SDK 的情况下编译代码是必需的。 出于同样的原因,已将 WM_THEMECHANGED
消息的 typedef
添加到 XPTheme.h 文件中。
历史
- 2002 年 1 月 30 日:初始版本
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。