上一篇實現單一視窗自繪,但實務專案需所有視窗統一風格。本文介紹如何將自繪邏輯封裝為基類 CTitleBarDlg,讓所有對話框繼承即可擁有一致外觀。
AfxWndProc,對話框只在 OnInitDialog 處理 WM_INITDIALOGWM_NCPAINT、WM_NCLBUTTONDOWN、WM_NCMOUSEMOVE、WM_SIZEBOOL CTitleBarDlg::OnInitDialog()
{
// 基類必要初始化 (不可修改)
m_ToolTip.Create(this, TTS_ALWAYSTIP);
m_bResizeFlag = TRUE;
CRect rc; GetClientRect(&rc);
m_OldSize = rc.Size();
if (!m_BaseInitialized)
{
m_BaseInitialized = TRUE;
CDialog::OnInitDialog(); // 呼叫 MFC 預設初始化
// === 衍生類別只能在這裡加入自有初始化 ===
// OnCustomInit(); // 可定義虛擬函式供衍生類覆寫
}
return TRUE;
}
CYourDlg : public CDialogCYourDlg.h/.cpp 中所有 CDialog 改為 CTitleBarDlg (含基類宣告、建構函式、訊息對應宏)#include "TitleBarDlg.h"UINT nIDTemplate, CWnd* pParent,改為 CWnd* pParent)CYourDlg* pDlg = new CYourDlg;
pDlg->Create(IDD_YOUR_DLG);
pDlg->ShowWindow(SW_SHOW);
// 注意:需自行管理記憶體,適當時機 delete pDlg
模態對話框 (DoModal) 目前不支援,因 MFC 內部對話框程序處理流程不同。若需模態效果,可用非模態 + Disable 父視窗模擬。
作者已建立完整開發模板,包含:
CTitleBarDlg 基類完整原始碼WM_SIZE 重排)需求者可聯繫作者取得。
| 問題 | 原因 | 解決方向 |
|---|---|---|
| 基類必須是主視窗 | 鉤子機制依賴主視窗 | 研究 SetWindowsHookEx 全域鉤子注入 |
| 僅支援非模態對話框 | 模態對話框有獨立訊息迴圈 | 模擬模態:非模態 + Disable 父視窗 + 訊息過濾 |
| 子類化控制項風格不一 | 標準控制項繪製由系統接管 | Owner-draw / 自繪控制項封裝 (CButtonXP, CEditXP...) |
統一風格自繪介面已具雛形,後續將探討:控制項子類化、動態佈局管理、主題切換機制。歡迎交流指教。
原始碼請參考附件。聯繫:song_0962@sina.com / QQ: 34544052