VC自绘按钮

看了吕鑫老师的视频,自己试着编写了一个自绘按钮控件。
YuButton.h头文件如下:

创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的邕宁网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

#pragma once  
#include "afxwin.h"  
class CYuButton :public CWnd  
{  
    private:  
        BOOL  m_bIsDown;  
        BOOL  m_bIsMove;  
        BOOL  _bMouseTrack;//鼠标追踪状态  
  
        CString  m_sCaption;  
        CFont    *m_pFont;  
          
    public:  
    CYuButton(void);  
    virtual ~CYuButton(void);  
  
    BOOL Create(LPCTSTR sCpation,DWORD dwStyle,CONST CRect & rt,CWnd * pParendWnd,  
                   UINT uId);  
    BOOL CreateEx(DWORD dwExStyle,LPCTSTR sCaption,DWORD dwStyle,CONST CRect & rt,  
CWnd * pParendWnd,UINT uId);  
    DECLARE_MESSAGE_MAP()  
    afx_msg void OnNcPaint();  
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);  
    afx_msg void OnPaint();  
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);  
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);  
  
    //鼠标按下  
    void DrawDown(CDC * pDC);  
    //鼠标移动  
    void DrawMove(CDC * pDC);  
    //字体  
    void SetFont(CFont * pFont);  
    CFont * GetFont();  
    afx_msg void OnKillFocus(CWnd* pNewWnd);  
    afx_msg void OnMouseHover(UINT nFlags, CPoint point);  
    afx_msg void OnMouseLeave();  
};

YuButton.cpp文件内容如下:

#include "StdAfx.h"  
#include "YuButton.h"  
  
  
CYuButton::CYuButton(void)  
{  
    WNDCLASS wd={CS_VREDRAW|CS_HREDRAW,::DefWindowProc};  
    wd.lpszClassName = _T("YUButton");  
  
    AfxRegisterClass(&wd);  
  
    m_bIsDown   = FALSE;  
    m_bIsMove   = FALSE;  
    _bMouseTrack = TRUE;  
}  
  
CYuButton::~CYuButton(void)  
{  
}  
  
BOOL CYuButton::Create(LPCTSTR sCaption,DWORD dwStyle,CONST CRect & rt,CWnd *  
pParendWnd,UINT uId)  
{  
    m_sCaption = sCaption;  
    m_pFont = pParendWnd->GetFont();  
    return CWnd::Create(_T("YUButton"),sCaption,dwStyle|WS_CHILD,rt,pParendWnd,uId);  
}  
  
BOOL CYuButton::CreateEx(DWORD dwExStyle,LPCTSTR sCaption,DWORD dwStyle,CONST CRect & rt,  
CWnd * pParendWnd,UINT uId)  
{  
    m_sCaption = sCaption;  
    return CWnd::CreateEx(dwExStyle,_T("YUButton"),sCaption,dwStyle|WS_CHILD,rt,  
                          pParendWnd,uId);  
}  
BEGIN_MESSAGE_MAP(CYuButton, CWnd)  
    ON_WM_NCPAINT()  
    ON_WM_ERASEBKGND()  
    ON_WM_PAINT()  
    ON_WM_LBUTTONDOWN()  
    ON_WM_LBUTTONUP()  
    ON_WM_MOUSEMOVE()  
    ON_WM_KILLFOCUS()  
    ON_WM_MOUSEHOVER()  
    ON_WM_MOUSELEAVE()  
END_MESSAGE_MAP()  
  
void CYuButton::OnNcPaint()  
{  
  
}  
  
BOOL CYuButton::OnEraseBkgnd(CDC* pDC)  
{  
    return true;//CWnd::OnEraseBkgnd(pDC);  
}  
  
void CYuButton::OnPaint()  
{  
    CPaintDC dc(this); // device context for painting  
    CRect rt;  
    GetClientRect(&rt);  
      
    if(!m_bIsDown )//未点击填充  
    {  
        CBrush brush(RGB(241,243,248));  
        dc.SelectObject(brush);  
        dc.FillRect(rt,&brush);  
    }  
    else  
        DrawDown(&dc);  
  
    if(m_bIsMove && !m_bIsDown)//鼠标移动  
    {  
        DrawMove(&dc);  
    }  
  
    CPen pen;//画边框  
    pen.CreatePen(PS_SOLID,1,RGB(85,134,233));  
    dc.SelectObject(pen);  
    dc.Rectangle(rt);  
  
    dc.SelectObject(m_pFont);//父窗口字体  
    dc.SetBkMode(TRANSPARENT);  
    dc.DrawText(m_sCaption,rt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);  
}  
  
void CYuButton::OnLButtonDown(UINT nFlags, CPoint point)  
{  
    // TODO: 在此添加消息处理程序代码和/或调用默认值  
    m_bIsDown = TRUE;  
    this->SetFocus();  
    this->Invalidate(TRUE);  
      
    CWnd::OnLButtonDown(nFlags, point);  
}  
  
void CYuButton::OnLButtonUp(UINT nFlags, CPoint point)  
{  
    // TODO: 在此添加消息处理程序代码和/或调用默认值  
    m_bIsDown = FALSE;  
  
    this->Invalidate(TRUE);  
  
    CWnd * pWnd = this->GetParent();  
  
    if(pWnd)  
        pWnd->SendMessage(WM_COMMAND,GetDlgCtrlID(),(LPARAM)this->GetSafeHwnd());  
  
    CWnd::OnLButtonUp(nFlags, point);  
}  
  
void CYuButton::OnMouseMove(UINT nFlags, CPoint point)  
{  
    if (_bMouseTrack)     //若允许追踪,则。   
    {  
        TRACKMOUSEEVENT csTME;  
        csTME.cbSize = sizeof (csTME);  
        csTME.dwFlags = TME_LEAVE|TME_HOVER;  
        csTME.hwndTrack = m_hWnd ;// 指定要追踪的窗口   
        csTME.dwHoverTime = 10;  // 鼠标在按钮上停留超过 10ms ,才认为状态为 HOVER  
        ::_TrackMouseEvent (&csTME); //开启 Windows 的 WM_MOUSELEAVE,WM_MOUSEHOVER 事件支持  
        _bMouseTrack=FALSE ;   // 若已经追踪,则停止追踪   
    }  
  
    CWnd::OnMouseMove(nFlags, point);  
}  
  
void CYuButton::DrawDown(CDC * pDC)  
{  
    CRect rt;  
    GetClientRect(&rt);  
  
    CBrush brush;  
    brush.CreateSolidBrush(RGB(124,180,233));  
    pDC->SelectObject(brush);  
    pDC->FillRect(rt,&brush);  
}  
  
void CYuButton::SetFont(CFont * pFont)  
{  
    m_pFont = pFont;  
}  
  
CFont * CYuButton::GetFont()  
{  
    return m_pFont;  
}  
  
void CYuButton::DrawMove(CDC * pDC)  
{  
    CRect rt;  
    GetClientRect(&rt);  
  
    CBrush brush;  
    brush.CreateSolidBrush(RGB(188,199,216));  
    pDC->SelectObject(brush);  
    pDC->FillRect(rt,&brush);  
}  
  
void CYuButton::OnKillFocus(CWnd* pNewWnd)  
{  
    CWnd::OnKillFocus(pNewWnd);  
    m_bIsMove = FALSE;  
    Invalidate(TRUE);  
}  
  
void CYuButton::OnMouseHover(UINT nFlags, CPoint point)  
{  
    m_bIsMove = TRUE;  
    Invalidate(TRUE);  
    CWnd::OnMouseHover(nFlags, point);  
}  
  
void CYuButton::OnMouseLeave()  
{  
    _bMouseTrack = TRUE;  
    m_bIsMove = FALSE;  
    Invalidate(TRUE);  
    CWnd::OnMouseLeave();  
}

在对话框窗口头文件中声明:CYuButton m_ok成员变量,然后OnInitDialog函数中创建自绘按钮:
(注意:对话框窗口头文件,须包含自绘按钮控件的.h文件YuButton.h)

BOOL CtestDlg::OnInitDialog()  
{  
    ...  
    CRect rc(20,20,120,43);  
    m_ok.Create(_T("确定"),WS_VISIBLE,rc,this,1290);  
    ...  
}

手动添加消息映射,为什么手动,因为自绘按钮,其ID不在资源中,所以不能用类向导管理,如下:

BEGIN_MESSAGE_MAP(CtestDlg, CDialogEx)  
   ...  
   ON_BN_CLICKED(1290,&CtestDlg::OnClickedOk)  
END_MESSAGE_MAP()

对话框窗口头文件中,声明相应的消息处理函数OnClickedOk,如下:

void OnClickedOk();

编写消息处理函数代码:

void CtestDlg::OnClickedOk()  
{  
    AfxMessageBox(_T("ok"));  
}

VC自绘按钮

代码很长,很多是自动生成的,主要的自绘过程都在OnPaint消息函数中完成。


网站名称:VC自绘按钮
新闻来源:http://pwwzsj.com/article/pdossg.html