您好,登錄后才能下訂單哦!
看了呂鑫老師的視頻,自己試著編寫了一個自繪按鈕控件。
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消息函數中完成。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。