1. 基本原理
主题在VC UI中的自动支持依赖于manifest文件,在VC程序向导中有一个“生成程序清单”的选项即生成该文件
XP Theme的实现由系统Commctrl.dll( CommCtrl32.dll in vista)完成
Manifest原型
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
</assembly>
2. ActiveX中的实现原理
使用ActiveX生成向导,可以发现“程序清单”选项没有了,所以COM默认并不支持manifest。
http://support.microsoft.com/kb/830033/zh-cn MSDN对于如何手工加入支持有了官方说明,这里扼要记录一下:
ü 加入预处理指令ISOLATION_AWARE_ENABLED
ü 将manifest文件添加到.RS资源中,资源名为RT_MANIFEST,ID为ISOLATIONAWARE_MANIFEST_RESOURCE_ID.
ü 注意 应用程序ID为1,DLL ID为2,ActiveX为3
3. 官方文档补充
根据官方的文档直接实现会不成功,需做一定改变。
ü ActiveX不能使用ATL向导生成,那是得不到theme支持的,即使增加了MFC支持也无用。ActiveX必须使用MFC Active控件向导生成。
ü Manifest文件后缀名必须为Mainifest,前缀不一定要与ActiveX同名。
ü Manifest在资源中的ID名根据官方文档需要定义为ISOLATIONAWARE_MANIFEST_RESOURCE_ID,这也不一定,使用任意ID名和ID值均可
ü 预处理指令ISOLATION_AWARE_ENABLED必需,我一般直接在stdafx.h头上定义 #define ISOLATION_AWARE_ENABLED 1
ü 在ActiveX中添加复合ATL控件或者ATL对话框,系统会询问“需要增加ATL支持”,当IDE做完这个工作以后,ActiveX的XP Theme即实现。
ü #define ISOLATION_AWARE_ENABLED 1是切换代码,注释掉,Theme即失效
4. VS2008具体实现步骤
1) MFC Active控件向导生成ActiveX
2) 资源视图\添加\资源\导入 theme.manifest 资源名称 RT_MANIFEST,或者直接输入数字24。
3) Stdafx.h头上添加代码#define ISOLATION_AWARE_ENABLED 1
4) 类视图\添加\类\ATL对话框,假设该对话框为TestDlg
5) ActiveX Ctrl添加方法
Void Test()
{
CTestDlg Dlg;
Dlg.DoModal();
}
6) 书写网页
<OBJECT ID="TestForm" CLASSID="CLSID:56A879F8-0DA1-4534-9D58-E551FF1C9339"></OBJECT>
<script>TestForm.test()</script>
CLSID定义在.idl文件中可以找到,其中的 [ uuid(56A879F8-0DA1-4534-9D58-E551FF1C9339),
helpstring("atl_threadtheme9 Control"), control ]
7) 书写复合控件
类视图\添加\类\ATL控件(选中复合控件)。
5. 关于应用程序的Theme支持
VC6需要将manifest文件保持与应用程序相同文件名才能生效。
VC.NET 从2005版本开始已经默认支持theme,自动生成的stdafx.h尾部已经有
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
也就是说VS2005开始的应用软件编写已经不需要程序员关系Theme问题了,注意宏定义里有Unicode,而一般程序员都习惯了普通的多字节字符集,这里有可能需要程序员做一点手工修改宏定义。
Theme前
Theme后