MFC的自绘位图按钮

下载源代码
总体效果图:

一.前言
    以前对位图自绘按钮很迷茫,一直想对位图自绘按钮有个了解,经过一段时间的搜集和开发,自己重写了一个按钮位图类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 – 标题框架未创建,导致函数调用失败
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值