Windows XP 主题 API 的托管 C++ 包装器 - 第二部分
这是对 Don Kackman 的 UxTheme 组件的更新,该组件最初为 Visual Studio 2003 编写。

引言
这是对 Don Kackman 出色的 UxTheme 控件 的更新发布,已移植到 VC 8.0。主题浏览器已更新,为浏览器界面添加了主题颜色细节。代码已清理,移除了旧语法。类名已略微修改以符合我的命名约定。(类名以 C 开头,结构体名以 S 开头。)我删除了对 vcclr.h 的引用。字符串处理使用 Marshal::StringToHGlobalAuto
进行。用于访问托管字符串的适当宏位于 stdafx.h 中。应 Don 的建议,我将命名空间从 System::Windows::Froms::Themes
更改为 UxThemeTool
。
背景
在我使用 .NET 2.0 开发 自定义按钮 时,我对 Don 的原始工作产生了兴趣。该工具允许我为我的按钮控件添加主题元素。但是,我真的很想在不使用 /clr:oldSyntax
设置的情况下使用它。因此,我在将此代码移植到 VS 2005 的过程中,花费了几天时间。
Using the Code
使用此代码实际上并没有什么困难。只需将 UxThemeTool.dll 的引用添加到您的 C# 或 VB.NET 项目中。您需要熟悉 Windows XP 或 Windows Server 2003 平台 SDK 中包含的主题 API。
初始化控件很简单。在您的应用程序的窗体中,将以下代码放在 form_load
方法中
// Call IsAppThemed first. This checks for theming before loading the UxTheme.dll.
// You do not want to access any theme methods if this property returns false.
if ( CUxTheme.IsAppThemed )
{
// Do something with themes here
}
else
{
MessageBox.Show( "Themes are not enabled" );
this.Close();
}
关注点
我能够使用 Microsoft 概述的 XML 注释命名法添加其他文档。但是,托管 C++ 的文档过程比 C# 要繁琐得多。
我惊讶于 VS 2003 C++ 编译器如此宽松。在移植 VS 2003 项目代码时,我发现一个类继承(实现)了一个接口,但其中一个函数在派生类中并未实现。VS 2003 (VC 7.1) 没有抱怨,但 VS 2005 (VC 8.0) 报告了一个错误。大部分移植工作都与语法更改有关(移除 _gc
构造并更改或添加 abstract 和 override 限定符)。我还想摆脱对 vcclr.h 的所有依赖。(即使未使用,我也不喜欢到处引入 gcroot.h。)
更新
我向 CUxTheme::GetColor
添加了一个默认颜色参数。我还从该方法中移除了一个 throw。事实证明,大多数主题颜色不存在(未使用)。与其抛出异常,我决定最好直接返回一个默认颜色。文件 Form1.cs 中的 treeView1_AfterSelect_1
方法说明了您可用于检索颜色的编码风格。
在 Visual Studio 2008 中编译
如果您想在 Visual Studio 2008 中编译此代码,请注意 Microsoft 在平台 SDK 随附的 tmschema.h 和 schemadef.h 中引入了一个 bug。这些文件开头包含 #pragma once
。由于 tmschema.def 旨在被包含两次到您的源代码中,因此 #pragma once
语句阻止了第二次解析正常进行。请参阅我博客中的帖子以获取更详细的解释。解决此问题的最简单方法是注释掉 tmschema.h 和 schemadef.h 顶部的 #pragma once
语句。您应该意识到,这些文件不包含 Vista 的更新。Microsoft 已更改了访问 Windows Vista 主题的内部结构。我正在努力更新代码以处理 Vista 主题。
历史
- 版本 1.0 2008 年 4 月 10 日
- 将代码从 VC 7.1 移植到 VC 8.0 的原始版本
- 移除了所有旧语法
- 版本 1.1 2008 年 4 月 24 日
- 更新了界面以显示主题颜色