下载源代码
总体效果图:
一.前言
以前对位图自绘按钮很迷茫,一直想对位图自绘按钮有个了解,经过一段时间的搜集和开发,自己重写了一个按钮位图类COwnerdrawBitmapButton。COwnerdrawBitmapButton是一个从CWnd类派生来的MFC控件。此按钮包含了两部分:一个背景色和一个前景色。如果你的操作系统是WinXP和XP,这个可用。背景是从当前资源文件加载位图,否则函数DrawFrameControl用来绘制按钮的背景。前景是用户定义一个单色位图(字形)在按钮背景色上面透明的绘制。
支持的功能:
● 标准或XP主题
● 12个预定义的背景样式
● 用户定义的前景色(单色位图)
● Buttons支持的状态:"NORMAL","HOT","PRESSED" 和 "DISABLED"
● 可以在标题栏区域创建按钮
● Dialog,SDI,MDI支持标题按钮
● 无闪烁绘图
● 内置的工具提示
二.COwnerdrawBitmapButton的使用
若你想在你的工程中使用COwnerdrawBitmapButton类,请看下面几个步骤:
1. 添加ThemeUtil.h, ThemeUtil.cpp, OwnerdrawBitmapButton.h, OwnerdrawBitmapButton.cpp, Tmschema.h and Schemadef.h到你的工程中。
2. 在你适当的头文件中包含OwnerdrawBitmapButton.h – 通常情况下,都是在对话框类中使用COwnerdrawBitmapButton。
4.创建标题框
在你对话框的OnInitDialog函数中,添加如下代码:
添加标题按钮的代码如下,在对话框中的OnInitDialog函数中调用AddCaptionButton:
6.在对话框类中,处理从标题按钮的消息WM_NOTIFY。当用户点击按钮时,按钮发送通知消息(NM_CLICK,NM_RCLICK,NM_DBLCLK,NM_RDBLCLK)给它的父窗口,如果你要做什么反应的话,处理这些消息。
7.千万不要忘了销毁主题框架,否则将会造成内存泄漏。
● 构造和析构函数
● 属性
● 操作函数
● 通知消息
● 错误代码
1. 构造和析构函数
2.属性
3.操作函数
AddCaptionButton:在标题区中插入一个新按钮
四.COwnerdrawBitmapButton类中的主要成员函数
1. COwnerdrawBitmapButton::COwnerdrawBitmapButton
说明:调用此函数去构造一个COwnerdrawBitmapButton对象。
2. COwnerdrawBitmapButton::Create
返回值:
若初始化对象成功则返回TRUE,否则返回FALSE。
参数:
● dwStyle – 指定按钮的样式
● rect – 指定按钮的大小和位置。它可以是CRect或者RECT类型
● pParentWnd – 指定按钮的父窗口
● nID – 指定按钮的ID
说明:
创建一个位图button,并且将它关联到一个COwnerdrawBitmapButton对象的一个实例。
3.COwnerdrawBitmapButton::CreateCaptionFrame
返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_ERRORCODE。
参数:
● PCaptionWnd – 指定主题区域的所属窗口
● nIDIcon – 指定标题图标的资源ID
说明:
创建一个标题框架。
4.COwnerdrawBitmapButton::DestroyCaptionFrame
返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
说明:
销毁主题框架。
5.COwnerdrawBitmapButton::GetCaptionButtonPtr
返回值:
若成功则指向一个COwnerdrawBitmapButton的对象,否则返回NULL。
参数:
● nButtonID – 主题按钮的ID
说明:
调用此函数将返回一个指向主题按钮的指针。
6.COwnerdrawBitmapButton::SetTooltipText
返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● sText – 指向一个包含有新提示文本的字符串对象。
说明:
改变button的提示文本
7.COwnerdrawBitmapButton::GetBkStyle
返回值:
为COwnerdrawBitmapButton对象返回一个按钮背景样式。
说明:
此函数是获取按钮控件背景样式的信息。
8.COwnerdrawBitmapButton::SetBkStyle
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
nBkStyle – 指定按钮的背景样式。
支持的背景样式有:
● CBNBKGNDSTYLE_CAPTION – frame buttons
● CBNBKGNDSTYLE_CLOSE
● CBNBKGNDSTYLE_MDI
● CBNBKGNDSTYLE_COMBO – combobox dropdown button
● CBNBKGNDSTYLE_SPINUP – spin buttons
● CBNBKGNDSTYLE_SPINDN
● CBNBKGNDSTYLE_SPINUPHOR
● CBNBKGNDSTYLE_SPINDNHOR
● CBNBKGNDSTYLE_SCROLLUP – scrollbar buttons
● CBNBKGNDSTYLE_SCROLLDOWN
● CBNBKGNDSTYLE_SCROLLLEFT
● CBNBKGNDSTYLE_SCROLLRIGHT
说明:
改变按钮的背景样式
9.COwnerdrawBitmapButton::GetGlyphBitmap
一个指向bitmap的句柄,假若之前未指定,则返回NULL
说明:
此函数将获取一个和button相关联的字形位图句柄
10.COwnerdrawBitmapButton::SetGlyphBitmap
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● hBmpGlyph – 位图句柄
说明:
此函数将一个新字形位图关联到按钮。
11.COwnerdrawBitmapButton::EnableWindow
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● bEnable– 指定给定窗口是否为可用。假如这个参数值为TRUE,则这个窗口是可用的。假如这个值为FALSE,则这个窗口是不可用的。
说明:
调用这个函数使窗口可用或不可用
12.COwnerdrawBitmapButton::AddCaptionButton
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● lpRect – 若fUserDefWidth为true,则指定button的宽度,否则忽略。
● nID – 指定button的id
● nBkStyle – 指定button的背景样式
● fUserDefWidth – 若为TRUE,则用户定义button的宽度
说明:
此函数的功能是在一个已存在的标题去插入一个新的按钮
五.通知消息
按钮控件支持以下通知代码:
● NM_CLICK – 用户点击了控件按钮的鼠标左键
● NM_RCLICK – 用户点击了控件按钮的鼠标右键
● NM_DBLCLK – 用户双击了控件按钮的鼠标左键
● NM_RDBLCLK – 用户双击了控件按钮的鼠标右键
六.错误代码
在控件按钮函数中,可能会返回下面的错误代码:
● CBNERRR_NOERROR – 操作成功
● CBNERR_OUTOFMEMORY – 可用内存不足,导致函数调用失败
● CBNERR_INCORRECTPARAMETER – 指定了错误的参数导函数调用失败
● CBNERR_INCORRECTBUTTONSTYLE – 指定错误按钮风格导致函数调用失败
● CBNERR_INCORRECTFRAMESTYLE – 未指定WS_CAPTION样式,导致函数调用失败
● CBNERR_INCORRECTFUNCCALL – 错误的函数调用(例如:ob.SetTooltipText(…),而这里ob是一个主题框架对象的一个实例)
● CBNERR_CREATEBUTTONFAILED – 创建按钮控件失败,导致函数调用失败
● CBNERR_CREATETOOLTIPCTRLFAILED – 创建提示控件失败,导致函数调用失败
● CBNERR_COPYIMAGEFAILED – 复制字形图片失败,导致函数调用失败
● CBNERR_SETWINDOWLONGFAILED – 调用SetWindowLong函数失败
● CBNERR_FRAMEALREADYCREATED – 标题框架已经存在,导致调用函数失败
● CBNERR_FRAMENOTCREATED – 标题框架未创建,导致函数调用失败
总体效果图:
一.前言
以前对位图自绘按钮很迷茫,一直想对位图自绘按钮有个了解,经过一段时间的搜集和开发,自己重写了一个按钮位图类COwnerdrawBitmapButton。COwnerdrawBitmapButton是一个从CWnd类派生来的MFC控件。此按钮包含了两部分:一个背景色和一个前景色。如果你的操作系统是WinXP和XP,这个可用。背景是从当前资源文件加载位图,否则函数DrawFrameControl用来绘制按钮的背景。前景是用户定义一个单色位图(字形)在按钮背景色上面透明的绘制。
支持的功能:
● 标准或XP主题
● 12个预定义的背景样式
● 用户定义的前景色(单色位图)
● Buttons支持的状态:"NORMAL","HOT","PRESSED" 和 "DISABLED"
● 可以在标题栏区域创建按钮
● Dialog,SDI,MDI支持标题按钮
● 无闪烁绘图
● 内置的工具提示
二.COwnerdrawBitmapButton的使用
若你想在你的工程中使用COwnerdrawBitmapButton类,请看下面几个步骤:
1. 添加ThemeUtil.h, ThemeUtil.cpp, OwnerdrawBitmapButton.h, OwnerdrawBitmapButton.cpp, Tmschema.h and Schemadef.h到你的工程中。
2. 在你适当的头文件中包含OwnerdrawBitmapButton.h – 通常情况下,都是在对话框类中使用COwnerdrawBitmapButton。
//OwnerdrawBitmapButtonDemoDlg.h : header file #include "OwnerdrawBitmapButton.h"3.在你的dialog头文件中,定义一个COwnerdrawBitmapButton类型的变量m_ctrlCaptionFrame。
// OwnerdrawBitmapButtonDemoDlg.h : header file class COwnerdrawBitmapButtonDemoDlg : CDialog { ...... private: COwnerdrawBitmapButton m_ctrlCaptionFrame; };
4.创建标题框
在你对话框的OnInitDialog函数中,添加如下代码:
//OwnerBitmapButtonDemoDlg.cpp : definition file m_ctrlCaptionFrame.CreateCaptionFrame(this,IDR_MAINFRAME);5.创建完主题框后,添加你需要的按钮
添加标题按钮的代码如下,在对话框中的OnInitDialog函数中调用AddCaptionButton:
// OwnerdrawBitmapButtonDemoDlg.cpp : definition file m_ctrlCaptionFrame.AddCaptionButton(CRect(0,0,0,0),1, CBNBKGNDSTYLE_CLOSE, FALSE); m_ctrlCaptionFrame.AddCaptionButton(CRect(0,0,150,0),2, CBNBKGNDSTYLE_CAPTION, TRUE); COwnerdrawBitmapButton* pBn1 = m_ctrlCaptionFrame.GetCaptionButtonPtr(1); if(pBn1) { CBitmap bmpGlyph1; bmpGlyph1.LoadBitmap(IDB_GLYPH1); pBn1->SetGlyphBitmap(bmpGlyph1); pBn1->SetTooltipText(_T("Double click to close the window, Right click to display the popup menu")); } COwnerdrawBitmapButton* pBn2 = m_ctrlCaptionFrame.GetCaptionButtonPtr(2); if(pBn2) { CBitmap bmpGlyph2; bmpGlyph2.LoadBitmap(IDB_GLYPH2); pBn2->SetGlyphBitmap(bmpGlyph2); pBn2->SetTooltipText(_T("Articles by Andrzej Markowski")); }
6.在对话框类中,处理从标题按钮的消息WM_NOTIFY。当用户点击按钮时,按钮发送通知消息(NM_CLICK,NM_RCLICK,NM_DBLCLK,NM_RDBLCLK)给它的父窗口,如果你要做什么反应的话,处理这些消息。
// OwnerdrawBitmapButtonDemoDlg.cpp : definition file BEGIN_MESSAGE_MAP(COwnerdrawBitmapButtonDemoDlg, CDialog) //{{AFX_MSG_MAP(COwnerdrawBitmapButtonDemoDlg) ON_NOTIFY(NM_DBLCLK, 1, OnBnDblClickedCaptionbn1) ON_NOTIFY(NM_RCLICK, 1, OnBnRClickedCaptionbn1) ON_NOTIFY(NM_CLICK, 2, OnBnClickedCaptionbn2) //}}AFX_MSG_MAP END_MESSAGE_MAP() .... void COwnerdrawBitmapButtonDemoDlg::OnBnDblClickedCaptionbn1 (NMHDR * pNotifyStruct, LRESULT * result) { CPoint pt; ::GetCursorPos(& pt); PostMessage(WM_SYSCOMMAND,SC_CLOSE,MAKEWORD(pt.x,pt.y)); } ....
7.千万不要忘了销毁主题框架,否则将会造成内存泄漏。
//OwnerdrawBitmapButtonDemoDlg.cpp : definition file void COwnerdrawBitmapButtonDemoDlg::OnDestroy() { m_ctrlCaptionFrame.DestroyCaptionFrame(); CDialog::OnDestroy(); }三.COwnerdrawBitmapButton类的成员
● 构造和析构函数
● 属性
● 操作函数
● 通知消息
● 错误代码
1. 构造和析构函数
COwnerdrawBitmapButton | 构造一个COwnerdrawBitmapButton对象 |
Create | 创建一个位图按钮,并且把它关联到COwnerdrawBitmapButton对象的实例 |
CreateCaptionFrame | 创建一个主题框架 |
DestoryCaptionFrame | 销毁主题框架 |
2.属性
GetCaptionButtonPtr | 返回一个标题按钮的指针 |
SetTooltipText | 设置按钮的提示文本 |
GetBkStyle | 获取按钮控件的背景风格信息 |
SetBkStyle | 设置按钮的背景风格 |
GetGlyphBitmap | 获取之前用SetGlyphBitmap设置字形位图的句柄 |
SetGlyphBitmap | 设置按钮上面的字形位图 |
EnableWindow | 设置按钮可用或不可用 |
3.操作函数
AddCaptionButton:在标题区中插入一个新按钮
四.COwnerdrawBitmapButton类中的主要成员函数
1. COwnerdrawBitmapButton::COwnerdrawBitmapButton
COwnerdrawBitmapButton();
说明:调用此函数去构造一个COwnerdrawBitmapButton对象。
2. COwnerdrawBitmapButton::Create
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID )
返回值:
若初始化对象成功则返回TRUE,否则返回FALSE。
参数:
● dwStyle – 指定按钮的样式
● rect – 指定按钮的大小和位置。它可以是CRect或者RECT类型
● pParentWnd – 指定按钮的父窗口
● nID – 指定按钮的ID
说明:
创建一个位图button,并且将它关联到一个COwnerdrawBitmapButton对象的一个实例。
3.COwnerdrawBitmapButton::CreateCaptionFrame
int CreateCaptionFrame( CWnd* pCaptionWnd, int nIDIcon );
返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_ERRORCODE。
参数:
● PCaptionWnd – 指定主题区域的所属窗口
● nIDIcon – 指定标题图标的资源ID
说明:
创建一个标题框架。
4.COwnerdrawBitmapButton::DestroyCaptionFrame
int DestroyCaptionFrame();
返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
说明:
销毁主题框架。
5.COwnerdrawBitmapButton::GetCaptionButtonPtr
COwnerdrawBitmapButton* GetCaptionButtonPtr( int nButtonID ) const;
返回值:
若成功则指向一个COwnerdrawBitmapButton的对象,否则返回NULL。
参数:
● nButtonID – 主题按钮的ID
说明:
调用此函数将返回一个指向主题按钮的指针。
6.COwnerdrawBitmapButton::SetTooltipText
int SetTooltipText( CString sText );
返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● sText – 指向一个包含有新提示文本的字符串对象。
说明:
改变button的提示文本
7.COwnerdrawBitmapButton::GetBkStyle
int GetBkStyle();
返回值:
为COwnerdrawBitmapButton对象返回一个按钮背景样式。
说明:
此函数是获取按钮控件背景样式的信息。
8.COwnerdrawBitmapButton::SetBkStyle
int SetBkStyle( int nBkStyle );返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
nBkStyle – 指定按钮的背景样式。
支持的背景样式有:
● CBNBKGNDSTYLE_CAPTION – frame buttons
● CBNBKGNDSTYLE_CLOSE
● CBNBKGNDSTYLE_MDI
● CBNBKGNDSTYLE_COMBO – combobox dropdown button
● CBNBKGNDSTYLE_SPINUP – spin buttons
● CBNBKGNDSTYLE_SPINDN
● CBNBKGNDSTYLE_SPINUPHOR
● CBNBKGNDSTYLE_SPINDNHOR
● CBNBKGNDSTYLE_SCROLLUP – scrollbar buttons
● CBNBKGNDSTYLE_SCROLLDOWN
● CBNBKGNDSTYLE_SCROLLLEFT
● CBNBKGNDSTYLE_SCROLLRIGHT
说明:
改变按钮的背景样式
9.COwnerdrawBitmapButton::GetGlyphBitmap
HBITMAP GetGlyphBitmap();返回值:
一个指向bitmap的句柄,假若之前未指定,则返回NULL
说明:
此函数将获取一个和button相关联的字形位图句柄
10.COwnerdrawBitmapButton::SetGlyphBitmap
int SetGlyphBitmap( HBITMAP hBmpGlyph );返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● hBmpGlyph – 位图句柄
说明:
此函数将一个新字形位图关联到按钮。
11.COwnerdrawBitmapButton::EnableWindow
int EnableWindow( BOOL bEnable = TRUE);返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● bEnable– 指定给定窗口是否为可用。假如这个参数值为TRUE,则这个窗口是可用的。假如这个值为FALSE,则这个窗口是不可用的。
说明:
调用这个函数使窗口可用或不可用
12.COwnerdrawBitmapButton::AddCaptionButton
int AddCaptionButton(LPCRECT lpRect, UINT nID, int nBkStyle,BOOL fUserDefWidth);返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● lpRect – 若fUserDefWidth为true,则指定button的宽度,否则忽略。
● nID – 指定button的id
● nBkStyle – 指定button的背景样式
● fUserDefWidth – 若为TRUE,则用户定义button的宽度
说明:
此函数的功能是在一个已存在的标题去插入一个新的按钮
五.通知消息
按钮控件支持以下通知代码:
● NM_CLICK – 用户点击了控件按钮的鼠标左键
● NM_RCLICK – 用户点击了控件按钮的鼠标右键
● NM_DBLCLK – 用户双击了控件按钮的鼠标左键
● NM_RDBLCLK – 用户双击了控件按钮的鼠标右键
六.错误代码
在控件按钮函数中,可能会返回下面的错误代码:
● CBNERRR_NOERROR – 操作成功
● CBNERR_OUTOFMEMORY – 可用内存不足,导致函数调用失败
● CBNERR_INCORRECTPARAMETER – 指定了错误的参数导函数调用失败
● CBNERR_INCORRECTBUTTONSTYLE – 指定错误按钮风格导致函数调用失败
● CBNERR_INCORRECTFRAMESTYLE – 未指定WS_CAPTION样式,导致函数调用失败
● CBNERR_INCORRECTFUNCCALL – 错误的函数调用(例如:ob.SetTooltipText(…),而这里ob是一个主题框架对象的一个实例)
● CBNERR_CREATEBUTTONFAILED – 创建按钮控件失败,导致函数调用失败
● CBNERR_CREATETOOLTIPCTRLFAILED – 创建提示控件失败,导致函数调用失败
● CBNERR_COPYIMAGEFAILED – 复制字形图片失败,导致函数调用失败
● CBNERR_SETWINDOWLONGFAILED – 调用SetWindowLong函数失败
● CBNERR_FRAMEALREADYCREATED – 标题框架已经存在,导致调用函数失败
● CBNERR_FRAMENOTCREATED – 标题框架未创建,导致函数调用失败