首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC 封裝動態創建按鈕類:繼承 CButton 重繪與消息響應

     編輯:程式設計疑難解答

需求

封裝一個類,支持動態創建按鈕、自定義繪制(Owner Draw)、響應點擊消息。

實現步驟

  1. 繼承 CButton,啟用 BS_OWNERDRAW 風格。
  2. 重寫 DrawItem:根據狀態(正常、懸停、按下、禁用)繪製背景、文字、圖標。
  3. 消息映射:處理 WM_MOUSEMOVE、WM_MOUSELEAVE 更新狀態並 Invalidate 觸發重繪。
  4. 動態創建:MyButton* btn = new MyButton(); btn->Create(_T("文字"), WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, rect, pParent, ID);。
  5. 清理:父窗口銷毀時 `delete btn;` 或用智能指針管理。

核心代碼骨架

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 + 狀態機 + 消息映射,即可封裝出功能完整、可動態創建的自繪按鈕類。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved