MFC CBitmapButton 类实现界面之美化按钮

下面,我们来说一下如何美化按钮?

第1步,我们先在对话框上放置两个按钮,一个是关闭按钮,另一个是最小化按钮,它们对应的ID分别是IDC_BUTTON_CLOSE和IDC_BUTTON_MIN,然后将我们的按钮设置为自绘制模式,方法如下:

选择按钮,右键属性,在属性列表中找到Owner Draw选项,将其设置为True,效果图如下:

再为它们添加两个成员变量,具体如下:

[cpp] 
  1. CButton m_btnClose;  
  2. CButton m_btnMin;  
第2步,我们新建一个类,继承自CBitmapButton,我们取名为CMyButton,为其添加3个成员变量,分别如下:


  1.  
    BOOL m_bTracked; 


  2.  
第3步,我们为CMyButton添加3个成员函数,分别如下:

[cpp] 
  1.         afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM); //自绘制函数   void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);  
CMyButton的声明最终如下:


  1. class CMyBitmapButton : public CBitmapButton
    {
DECLARE_DYNAMIC(CMyBitmapButton)


public:
CMyBitmapButton();
virtual ~CMyBitmapButton();
private:
BOOL m_bTracked;


protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};  
第4步,我们实现OnMouseMove函数,它的功能是为按钮背景图片和父窗口背景图片成员函数初始化,具体如下:

[cpp] 
  1. void CMyButton::OnMouseMove(UINT nFlags, CPoint point)  
  2. {  
  3.            if (!m_bTracked)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.dwHoverTime = 0;
tme.hwndTrack = m_hWnd;
TrackMouseEvent(&tme);


m_bTracked = TRUE;
Invalidate(FALSE);
}
CBitmapButton::OnMouseMove(nFlags, point); }  
第5步,我们实现InitMyButton函数,它的功能是调整按钮在对话框上的位置,其中的参数代表该按钮在父窗口的左上角X坐标,Y坐标,宽度,高度,最后一个参数是为PNG格式图片准备的,如果是PNG带透明色的图片,需要对它进行特殊处理,具体定义如下:


  1. LRESULT CMyButton::OnMouseLeave(WPARAM     wParam, LPARAM   lParam)  
  2. {  
  3.    m_bTracked = FALSE;
Invalidate(FALSE);


CBitmapButton::OnMouseLeave();
return 0; }  

第6步,我们实现DrawItem函数,它是美化Button的核心函数,当我们将Button设置为自绘制后,每次按钮需要刷新,重新绘制的时候,MFC框架会调用它的DrawItem函数,在这个函数中,我们可以根据按钮当前的状态为其贴上相应的背景图。当我们按钮按钮的时候,为其贴上被按下的背景图;当我们的按钮获取焦点的时候,为其贴上获取焦点的背景图;当我们的按钮没有焦点,我们为其贴上默认的背景图片,它们对应的位置前面已经说过。为了避免闪烁,我们采用双缓冲的方式,具体代码如下:

[cpp] 
  1. void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
  2. {  
  3.    ASSERT(lpDrawItemStruct != NULL);
// must have at least the first bitmap loaded before calling DrawItem 
ASSERT(m_bitmap.m_hObject != NULL);     // required 


// use the main bitmap for up, the selected bitmap for down 
CBitmap* pBitmap = &m_bitmap;
UINT state = lpDrawItemStruct->itemState;
if ((state & ODS_SELECTED) && m_bitmapSel.m_hObject != NULL)
pBitmap = &m_bitmapSel;
//else if ((state & ODS_FOCUS) && m_bitmapFocus.m_hObject != NULL) 
//pBitmap = &m_bitmapFocus;   // third image for focused 
else if ((state & ODS_DISABLED) && m_bitmapDisabled.m_hObject != NULL)
pBitmap = &m_bitmapDisabled;   // last image for disabled 
else if (m_bTracked && m_bitmapFocus.m_hObject != NULL)
pBitmap = &m_bitmapFocus;   // third image for focused 


// draw the whole button 
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap* pOld = memDC.SelectObject(pBitmap);
if (pOld == NULL)
return;     // destructors will clean up 


CRect rect;
rect.CopyRect(&lpDrawItemStruct->rcItem);
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOld);     return;   }  

第7步,用CMyButton替代对话框头文件中的CButton。

第8步,在对话框的InitDialog中,对两个按钮进行初始化,具体如下:

[cpp] 
  1.         m_btnClose.LoadBitmaps(IDB_BITMAP_CLOSE_B, IDB_BITMAP_CLOSE_B, IDB_BITMAP_CLOSE_A, 0);
m_btnClose.SizeToContent();

第9步,编译程序结束
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值