想讓程式介面脫離標準控制項框架?自繪功能是關鍵。本文完整記錄從零建立 XP 風格 CXPButton 類別的過程,涵蓋設計思路、核心難點突破、使用方法與完整原始碼結構,是學習 MFC 自繪控制項的最佳範例。
自繪按鈕必須定義各狀態外觀:
參考 Windows XP 原生按鈕風格設計,確保視覺一致性。
PreSubclassWindow() 設定 BS_OWNERDRAW 樣式,觸發 DrawItem() 重繪機制WM_MOUSEMOVE 呼叫 TrackMouseEvent() 註冊 TME_LEAVE | TME_HOVER,觸發 WM_MOUSELEAVE/WM_MOUSEHOVER 實現懸停/離開偵測LPDRAWITEMSTRUCT 提供的狀態、矩形、DC 等資訊,執行實際繪圖邏輯這兩個訊息無法透過類別精靈加入,需手動:
// 在 .h 檔宣告
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
afx_msg LRESULT OnMouseHover(WPARAM, LPARAM);
// 在 .cpp 訊息對應表
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
// WM_MOUSEMOVE 中啟用追蹤
void CXPButton::OnMouseMove(UINT nFlags, CPoint point) {
if (!m_bTracking) {
TRACKMOUSEEVENT tme = {sizeof(tme), TME_LEAVE | TME_HOVER, m_hWnd, 1};
m_bTracking = _TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
}
此結構是自繪的資訊中樞:
| 成員 | 用途 |
|---|---|
itemState | 控制項狀態旗標(ODS_SELECTED、ODS_FOCUS、ODS_HOTLIGHT 等) |
rcItem | 控制項矩形區域(座標原點為控制項左上角) |
hDC | 繪圖裝置內容句柄 |
itemAction | 繪圖行為(ODA_DRAWENTIRE、ODA_FOCUS、ODA_SELECT) |
掌握此結構,即可根據狀態組合繪製任意視覺效果。
IDC_BUTTON1)m_btnNormal,類型選 CXPButton.clw 檔並重開專案,選擇「Yes」→「Add All」重建類別資訊BS_OWNERDRAW、指定固定字型防系統字型影響DrawItem():繪圖順序建議「外框→底色→文字→內框」文件包含 CtlType(ODT_BUTTON、ODT_MENU 等)、itemState(ODS_HOTLIGHT、ODS_DEFAULT 等)、itemAction 等所有旗標的詳細中文說明,可作為開發時的快速查閱手冊。
CXPButton 不僅是一個可用的按鈕類別,更是一份完整的 MFC 自繪控制項開發教學案例。原始碼開放,可直接整合專案或作為客製化控制項的起點。