一.前言
以前对位图自绘按钮很迷茫,一直想对位图自绘按钮有个了解,经过一段时间的搜集和开发,自己重写了一个按钮位图类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。
1.//OwnerdrawBitmapButtonDemoDlg.h : header file 2. #include "OwnerdrawBitmapButton.h"3.在你的dialog头文件中,定义一个COwnerdrawBitmapButton类型的变量m_ctrlCaptionFrame。
1.// OwnerdrawBitmapButtonDemoDlg.h : header file 2. class COwnerdrawBitmapButtonDemoDlg : CDialog 3. { 4. ...... 5. private: 6. COwnerdrawBitmapButton m_ctrlCaptionFrame; 7. };4.创建标题框
在你对话框的OnInitDialog函数中,添加如下代码:
1.//OwnerBitmapButtonDemoDlg.cpp : definition file 2.m_ctrlCaptionFrame.CreateCaptionFrame(this,IDR_MAINFRAME);5.创建完主题框后,添加你需要的按钮
添加标题按钮的代码如下,在对话框中的OnInitDialog函数中调用AddCaptionButton:
01.// OwnerdrawBitmapButtonDemoDlg.cpp : definition file 02.m_ctrlCaptionFrame.AddCaptionButton(CRect(0,0,0,0),1, 03. CBNBKGNDSTYLE_CLOSE, FALSE); 04.m_ctrlCaptionFrame.AddCaptionButton(CRect(0,0,150,0),2, 05. CBNBKGNDSTYLE_CAPTION, TRUE); 06.COwnerdrawBitmapButton* pBn1 = m_ctrlCaptionFrame.GetCaptionButtonPtr(1); 07.if(pBn1) 08.{ 09. CBitmap bmpGlyph1; 10. bmpGlyph1.LoadBitmap(IDB_GLYPH1); 11. pBn1->SetGlyphBitmap(bmpGlyph1); 12. pBn1->SetTooltipText(_T("Double click to close the window, 13. Right click to display the popup menu")); 14. } 15.COwnerdrawBitmapButton* pBn2 = m_ctrlCaptionFrame.GetCaptionButtonPtr(2); 16.if(pBn2) 17.{ 18. CBitmap bmpGlyph2; 19. bmpGlyph2.LoadBitmap(IDB_GLYPH2); 20. pBn2->SetGlyphBitmap(bmpGlyph2); 21. pBn2->SetTooltipText(_T("Articles by Andrzej Markowski")); 22.}6.在对话框类中,处理从标题按钮的消息WM_NOTIFY。当用户点击按钮时,按钮发送通知消息(NM_CLICK,NM_RCLICK,NM_DBLCLK,NM_RDBLCLK)给它的父窗口,如果你要做什么反应的话,处理这些消息。
01.// OwnerdrawBitmapButtonDemoDlg.cpp : definition file 02. BEGIN_MESSAGE_MAP(COwnerdrawBitmapButtonDemoDlg, CDialog) 03. //{{AFX_MSG_MAP(COwnerdrawBitmapButtonDemoDlg) 04. ON_NOTIFY(NM_DBLCLK, 1, OnBnDblClickedCaptionbn1) 05. ON_NOTIFY(NM_RCLICK, 1, OnBnRClickedCaptionbn1) 06. ON_NOTIFY(NM_CLICK, 2, OnBnClickedCaptionbn2) 07. //}}AFX_MSG_MAP 08. END_MESSAGE_MAP() 09. .... 10. void COwnerdrawBitmapButtonDemoDlg::OnBnDblClickedCaptionbn1 11. (NMHDR * pNotifyStruct, LRESULT * result) 12.{ 13. CPoint pt; 14. ::GetCursorPos(& pt); 15. PostMessage(WM_SYSCOMMAND,SC_CLOSE,MAKEWORD(pt.x,pt.y)); 16.} 17.....7.千万不要忘了销毁主题框架,否则将会造成内存泄漏。
1.//OwnerdrawBitmapButtonDemoDlg.cpp : definition file 2. void COwnerdrawBitmapButtonDemoDlg::OnDestroy() 3.{ 4. m_ctrlCaptionFrame.DestroyCaptionFrame(); 5. CDialog::OnDestroy(); 6.}三.COwnerdrawBitmapButton类的成员
● 构造和析构函数
● 属性
● 操作函数
● 通知消息
● 错误代码
1. 构造和析构函数
|
COwnerdrawBitmapButton |
构造一个COwnerdrawBitmapButton对象 |
|
Create |
创建一个位图按钮,并且把它关联到COwnerdrawBitmapButton对象的实例 |
|
CreateCaptionFrame |
创建一个主题框架 |
|
DestoryCaptionFrame |
销毁主题框架 |
2.属性
|
GetCaptionButtonPtr |
返回一个标题按钮的指针 |
|
SetTooltipText |
设置按钮的提示文本 |
|
GetBkStyle |
获取按钮控件的背景风格信息 |
|
SetBkStyle |
设置按钮的背景风格 |
|
GetGlyphBitmap |
获取之前用SetGlyphBitmap设置字形位图的句柄 |
|
SetGlyphBitmap |
设置按钮上面的字形位图 |
|
EnableWindow |
设置按钮可用或不可用 |
3.操作函数
AddCaptionButton:在标题区中插入一个新按钮
四.COwnerdrawBitmapButton类中的主要成员函数
1. COwnerdrawBitmapButton::COwnerdrawBitmapButton
1.COwnerdrawBitmapButton();说明:调用此函数去构造一个COwnerdrawBitmapButton对象。
2. COwnerdrawBitmapButton::Create
1.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
1.int CreateCaptionFrame( CWnd* pCaptionWnd, int nIDIcon );返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_ERRORCODE。
参数:
● PCaptionWnd – 指定主题区域的所属窗口
● nIDIcon – 指定标题图标的资源ID
说明:
创建一个标题框架。
4.COwnerdrawBitmapButton::DestroyCaptionFrame
1.int DestroyCaptionFrame();返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
说明:
销毁主题框架。
5.COwnerdrawBitmapButton::GetCaptionButtonPtr
1.COwnerdrawBitmapButton* GetCaptionButtonPtr( int nButtonID ) const;返回值:
若成功则指向一个COwnerdrawBitmapButton的对象,否则返回NULL。
参数:
● nButtonID – 主题按钮的ID
说明:
调用此函数将返回一个指向主题按钮的指针。
6.COwnerdrawBitmapButton::SetTooltipText
1.int SetTooltipText( CString sText );返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● sText – 指向一个包含有新提示文本的字符串对象。
说明:
改变button的提示文本
7.COwnerdrawBitmapButton::GetBkStyle
1.int GetBkStyle();返回值:
为COwnerdrawBitmapButton对象返回一个按钮背景样式。
说明:
此函数是获取按钮控件背景样式的信息。
8.COwnerdrawBitmapButton::SetBkStyle
1.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
1.HBITMAP GetGlyphBitmap();返回值:
一个指向bitmap的句柄,假若之前未指定,则返回NULL
说明:
此函数将获取一个和button相关联的字形位图句柄
10.COwnerdrawBitmapButton::SetGlyphBitmap
1.int SetGlyphBitmap( HBITMAP hBmpGlyph );返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● hBmpGlyph – 位图句柄
说明:
此函数将一个新字形位图关联到按钮。
11.COwnerdrawBitmapButton::EnableWindow
1.int EnableWindow( BOOL bEnable = TRUE);返回值:
若成功返回CBNERRR_NOERROR,否则返回CBNERRR_NOERRORCODE。
参数:
● bEnable– 指定给定窗口是否为可用。假如这个参数值为TRUE,则这个窗口是可用的。假如这个值为FALSE,则这个窗口是不可用的。
说明:
调用这个函数使窗口可用或不可用
12.COwnerdrawBitmapButton::AddCaptionButton
1.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 – 标题框架未创建,导致函数调用失败