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"));  
}

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

时间: 09-18

VC自绘按钮的相关文章

vc++实现禁用按钮

在VC++中,按钮关联了快捷键,现要禁用按钮,用了 (CButton*)GetDlgItem(IDC_BUTTON)->EnableWindow(FALSE); 虽然窗口中按钮变成灰色,但是快捷键仍然有效. 当然有一个办法是在OnButton()中做一定的修改来达到目的. 但是怎样才能更简单地实现完全禁用按钮? 多谢.在OnButton()里面加一段语句if (!(CButton*)GetDlgItem(IDC_BUTTON)->IsWindowEnabled(){return;}vc++实现

VC,VB程序按钮、图标样式美化

此处的"美化"指的不是通过代码进行美化你的程序.关于想进一步优化自己的程序界面的,不妨去了解下SkinSharp吧.本文提及的是利用第三方资源编辑软件在不更改程序任何框架和代码的前提下实现对界面的简单美化. 1.Windows2000按钮样式转为Windows XP按钮样式 两种按钮的差别比较容易区分,典型的就是VC6和VS2010开发出的MFC程序界面.前者的按钮是黑白的,后者有渲染效果 VC6样式: VS2010样式 细心的读者应该发现我这两个界面的icon是相同的.没错,我是用V

VC自绘控件框架

这是一个按钮自绘的框架,其他控件也类似 //.h头文件 #pragma once #include "afxwin.h" #include "MemDC.h"//封装内存绘图类 class CYuButton :public CWnd {     private: BOOL  m_bIsDown; BOOL  m_bIsMove; BOOL  _bMouseTrack; CString  m_sCaption; CFont    *m_pFont;         

vc++6.0工具栏自绘按钮程序

实现按钮自绘,界面. 主对话框文件: // TitleBarDlg.cpp : implementation file // #include "stdafx.h" #include "TitleBar.h" #include "TitleBarDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif

win32自绘按钮,使用GDI+(二)

解决上一篇的两个问题. 一,按钮背景透明 方法是,在绘制按钮之前,向按钮的父窗口发生WM_CTLCOLORBTN消息.该消息返回一个画刷句柄,系统使用该画刷句柄画出按钮的背景.所以我们在处理这个消息的时候,为系统返回一个空的画刷句柄就可以了. 直接在回调函数中添加代码 1 case WM_CTLCOLORBTN: 2 { 3 HBRUSH hBrush; 4 //hBrush = CreateSolidBrush(RGB(255, 0, 0)); 5 hBrush=(HBRUSH)GetStoc

继承CWnd自绘按钮

头文件: //头文件 #pragma once // CLhsButton #define MYWM_BTN_CLICK WM_USER+3001 //关闭按钮单击响应 //tab按钮的状态 enum ButtonState { BTN_STATE_NOR = 0, BTN_STATE_DOWN = 1, }; class CLhsButton : public CWnd { DECLARE_DYNAMIC(CLhsButton) public: CLhsButton(); virtual ~C

VC 自绘CListCtrl类

http://www.codeproject.com/listctrl/quicklist.asp http://www.codeproject.com/listctrl/ctooltiplistctrl.asp 实现功能:鼠标在ListCtrl上滑动的时候,滑动到哪一行哪一行就高亮,有且仅有一条是高亮的. 如何实现下面两个功能: 1.当鼠标离开ListCtrl的时候,高亮行取消高亮. 2.更改高亮行的背景色,默认是蓝色的,客户想要其它的颜色. //自绘CListCtrl类,重载虚函数DrawI

VC自绘 史上最强大且精简的记分点名软件

创意.诚意.潜力之作 史上最强大且精简的记分点名软件. 教育专家推荐的课堂软件,当老师的错过了,错过了肯定是您的损失. [一]个性开头白 唐诗.名言.英文.自定义 并可语音朗读出 [二]个性小组名 小组口号 并醒目显示 [三] 完善的积分机制 [四]  QQ管理界面 www.gudianxiaoshuo.com                

MFC 自绘按钮 消息响应

单检测到按下消息时,发送一个消息 m_pParent->PostMessage(WM_COMMAND, IDC_BUTTON1); 然后再在消息映射里建立映射. ON_COMMAND(IDC_BUTTON1, &CMyDlg::OnBUTTON1)