介绍 我正在更新一个我用NT和Win2K开发的程序,我在整个程序中都使用了CBitmapButton。在移植程序的新版本以在XP下运行时,我注意到我在VC7中“旧的”位图按钮没有样式意识,并且使应用程序看起来有点过时。在网上搜索后,我注意到了其他几个悬停按钮的例子,但没有一个考虑到我对CBitmapButton的投资。我想要一个CBitmapButton派生类,我可以插入到我的旧应用。这是我在这里提交的第一篇文章,请原谅我的散文式。 我的主题是什么? 使用UXTHEME。DLL,我在Ewan Ward. 的一个示例项目中发现。我创建了一个新的CTheme类。如果您愿意,您可以使用WTL CTheme类。然而,,我刚刚创建了一个适合我的目的。 如果你正在创建一个MFC文档/视图应用程序,那么在CMainFrame中声明一个CTheme成员m_theme,如果它是一个基于对话框的应用程序-在CDialog派生的主窗口中声明一个CTheme成员m_theme:Hide 复制Code
CTheme m_theme;
在文档/视图应用程序中,在CMainFrame::OnCreate()中,或在OnInitDialog()中基于对话框的应用程序中添加:Hide 复制Code
m_theme.Init(m_hWnd);
Init()函数调用函数GetAppearance()来查看样式是XP样式还是Windows Classic样式。实际上,它只是检查当前的操作系统是否为XP,以及是否选择了经典样式。隐藏,收缩,复制Code
BOOL CTheme::GetAppearance(void) { // For XP - Detect if the Window Style is Classic or XP OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); if (osvi.dwMajorVersion < 5) // Earlier than XP return FALSE; ///////////////////////////////////////////////////// HKEY hKey; CString szSubKey = _T("Control Panel\Appearance"); CString szCurrent = _T("Current"); DWORD dwSize = 200; unsigned char * pBuffer = new unsigned char[dwSize]; memset(pBuffer, 0, dwSize); if (RegOpenKeyEx(HKEY_CURRENT_USER, (LPCSTR)szSubKey, 0L, KEY_READ, &hKey) != ERROR_SUCCESS) { // Can't find it delete []pBuffer; return FALSE; } RegQueryValueEx(hKey, szCurrent, NULL, NULL, pBuffer, &dwSize); RegCloseKey(hKey); szCurrent = pBuffer; delete []pBuffer; if (szCurrent == _T("Windows Standard")) return FALSE; return TRUE; }
如果没有调用CTheme::Init(),那么CHoverBitmapButton将默认使用旧的按钮样式。如果样式是XP样式,则加载DLL。 位图呢? 您应该使用与在普通CBitmapButton类中使用的相同的位图,其中包括绘制边缘。对于XP样式的按钮,创建(或复制)白色背景的旧按钮位图——你不必像以前的CBitmapButton那样绘制边缘。例如,我有一个按钮: (direct .bmp),对于XP样式,我创建了一个新的位图:(xpdirect .bmp)。对于旧的样式,我还有F X和D位图;对于XP的样式,我只需要U和X位图。我也以相同的方式命名资源——除了我在新的XP风格的资源名称前加上了字母XP. 这对于CHoverBitmapButton类区分XP样式和经典样式的位图很重要。您可以自己使用公共函数CHoverBitmapButton::SetPrefix()来设置前缀——或者只使用默认值。 用CHoverBitmapButton::Load()或CHoverBitmapButton::AutoLoad()加载位图与以前一样。 在示例对话框应用程序中——在OnInitDialog()中:Hide 复制Code
m_CtrlButton.Load(IDC_DIRECT, this, &m_theme);
在文档/视图应用程序中,你可以使用通常的方法:隐藏。复制Code
m_CtrlButton.AutoLoad(IDC_DIRECT, this);
在CHoverBitmapButton构造函数中,m_pTheme可以通过CHoverBitmapButton::GetFrame()来初始化变量m_theme。 所以对于这两种样式-位图资源将被命名为: 在XP模式下,你可以使用上面的“DIRECTU”和下面的“DIRECTF”来设置你的“XPDIRECTX”。 新的XP风格按钮将使用DLL函数DrawThemeBackground绘制按钮纹理和边缘。 改变我的风格 为了处理消息WM_THEMECHANGED,你必须设置WINVER, _WIN32_WINNT, _WIN32_WINDOWS和_WIN32_IE都等于stdafx.h 如果你不想检测变化,然后你可以有一个应用程序运行在以前的版本的Windows,但如果你唯一的目标是XP,然后这个例子包括代码处理WM_THEMECHANGED消息。 包括 添加线条隐藏复制Code
#include "ThemeLib.h"
对stdafx.h 使用类 如前所述,对话框类型应用程序与文档/视图类型应用程序的用法略有不同。 对话框类型应用程序: 在主CDialog派生类的头文件中:隐藏复制Code
#include "theme.h" #include "HoverBitmapButton.h"
并添加一个公共类成员:Hide 复制Code
CTheme m_theme;
把你用ClassWizard添加的CButton控件改为:Hide复制Code
CHoverBitmapButton m_CtrlButton;
对话框:隐藏复制Code
m_theme.Init(m_hWnd); m_CtrlButton.Load(IDC_DIRECT, this, &m_theme);
文档/视图类型应用程序: 在大型机。h:隐藏,复制Code
#include "theme.h"
并添加一个公共类成员:Hide 复制Code
CTheme m_theme;
在CMainFrame中::OnCreate():Hide 复制Code
m_theme.Init(m_hWnd);
在一个CDialog派生类中有一个按钮,在头文件中:Hide 复制Code
#include "HoverBitmapButton.h"
把你用ClassWizard添加的CButton控件改为:Hide复制Code
CHoverBitmapButton m_CtrlButton;
对话框:隐藏复制Code
m_ CtrlButton.AutoLoad(IDC_DIRECTORY, this);
代码更改要求: 对于Doc/View,更改HoverBitmapButton.cpp中的代码,其中的注释显示Doc/View。 在创造者中:隐藏复制Code
CHoverBitmapButton::CHoverBitmapButton() { m_bHovering = FALSE; // remove the comments from these 2 lines: m_pTheme = &(GetFrame()->m_theme); // If Doc/View m_theme is // a member of CMainFrame m_bXPTheme = m_pTheme->m_bXPTheme; m_szXPPrefix = _T("XP"); m_bThemeChanging = FALSE; }
在头文件和代码文件中,取消函数Hide的注释。复制Code
CMainFrame* CHoverBitmapButton::GetFrame(void)
感谢Ewan Ward在他的原生Win32主题意识所有者-draw中所做的工作没有MFC控件。 本文转载于:http://www.diyabc.com/frontweb/news732.html