封裝一個類,支持動態創建按鈕、自定義繪制(Owner Draw)、響應點擊消息。
CButton,啟用 BS_OWNERDRAW 風格。DrawItem:根據狀態(正常、懸停、按下、禁用)繪製背景、文字、圖標。WM_MOUSEMOVE、WM_MOUSELEAVE 更新狀態並 Invalidate 觸發重繪。MyButton* btn = new MyButton(); btn->Create(_T("文字"), WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, rect, pParent, ID);。class CMyButton : public CButton {
DECLARE_DYNAMIC(CMyButton)
public:
CMyButton() : m_state(NORMAL) {}
enum State { NORMAL, HOVER, PUSHED, DISABLED };
protected:
State m_state;
CFont m_font;
// 繪製
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) override;
// 消息
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnMouseLeave();
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyButton, CButton)
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
END_MESSAGE_MAP()
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) {
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CRect rect(lpDIS->rcItem);
// 背景
COLORREF bg = (m_state == PUSHED) ? RGB(0,120,215) :
(m_state == HOVER) ? RGB(0,100,180) : RGB(30,30,30);
pDC->FillSolidRect(rect, bg);
// 文字
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255,255,255));
CString text; GetWindowText(text);
pDC->DrawText(text, rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
void CMyButton::OnMouseMove(UINT nFlags, CPoint point) {
if (m_state != HOVER && m_state != PUSHED) {
m_state = HOVER;
Invalidate();
TRACKMOUSEEVENT tme = {sizeof(tme), TME_LEAVE, m_hWnd, 0};
_TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
}
void CMyButton::OnMouseLeave() {
m_state = NORMAL;
Invalidate();
CButton::OnMouseLeave();
}
void CMyDialog::OnInitDialog() {
CDialogEx::OnInitDialog();
m_btnReset = new CMyButton();
m_btnReset->Create(_T("重置"), WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,
CRect(10,10,100,40), this, IDC_BTN_RESET);
}
繼承 CButton + BS_OWNERDRAW + 狀態機 + 消息映射,即可封裝出功能完整、可動態創建的自繪按鈕類。