博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

(文章转载)

Posted on 2012-06-26 17:50  SmarTom  阅读(181)  评论(0)    收藏  举报

一.前言

以前对位图自绘按钮很迷茫,一直想对位图自绘按钮有个了解,经过一段时间的搜集和开发,自己重写了一个按钮位图类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 – 标题框架未创建,导致函数调用失败