MFC (Microsoft Foundation Class Library) 將數百個 C++ 類組織成一個協同工作的框架。它的目標單一而明確:讓程式設計師以最小成本構建 Windows 應用程式。相較於裸寫 Win32 SDK,MFC 提供了:
程式設計師的任務變為:「在框架預留的虛擬函數、訊息處理器、覆寫點填入業務邏輯」。
| 封裝層面 | 核心類/機制 | 解決的問題 |
|---|---|---|
| Win32 API | CWnd、CDC、CFile、CThread 等 | 將 HWND、HDC、HANDLE 等句柄包裝為 C++ 物件,成員函數對應 API,m_hWnd 保存句柄。 |
| 應用程式概念 | CWinApp、CDocument、CView、CFrameWnd | 封裝「註冊視窗類、建立視窗、訊息迴圈、文檔/視圖分離」等樣板式流程。 |
| COM/OLE | COleClientItem、COleServerItem、COleControl | 隱藏 IUnknown、IOleObject 等繁瑣介面實作,提供高階 OLE 程式設計介面。 |
| 資料存取 (ODBC/DAO) | CDatabase、CRecordset、CDaoDatabase | 封裝 ODBC API,提供記錄集導航、欄位交換 (RFX)、事務控制等資料庫程式設計模式。 |
MFC 採用單一繼承樹,根類別為 CObject:
CObject (根類別)
├─ CCmdTarget (訊息處理基礎)
│ ├─ CWinThread (執行緒)
│ │ └─ CWinApp (應用程式)
│ ├─ CWnd (視窗基礎)
│ │ ├─ CFrameWnd (框架視窗)
│ │ │ ├─ CMDIFrameWnd (MDI 主框架)
│ │ │ └─ CMDIChildWnd (MDI 子框架)
│ │ ├─ CView (視圖)
│ │ │ ├─ CScrollView
│ │ │ ├─ CListView
│ │ │ └─ CTreeView
│ │ └─ CDialog (對話框)
│ └─ CDocument (文檔)
└─ CFile (檔案)
├─ CStdioFile
└─ CMemFile
設計原則:每類對象有一個基類,派生出具體功能類。程式設計師從適當基類繼承,覆寫虛擬函數或加入訊息處理器,實現特定行為。
CWnd 封裝了上百個 Windows 訊息(WM_PAINT、WM_MOUSEMOVE…),若全部做成虛擬函數:
MFC 發明訊息映射:
AFX_MSGMAP 記錄「訊息 ID → 處理函數指標」。CCmdTarget::OnCmdMsg 遍歷映射表,找到對應處理器並呼叫。DECLARE_MESSAGE_MAP() / BEGIN_MESSAGE_MAP() / ON_COMMAND() / ON_WM_PAINT() 自動生成映射表項目。優點:零開銷(未使用的訊息無映射項)、類型安全、易於 ClassWizard 維護。
AppWizard 根據專案類型產生不同「模板」(一組協同工作的類):
| 模板類型 | 核心類組合 | 適用場景 |
|---|---|---|
| SDI (單文檔介面) | CWinApp + CFrameWnd + CDocument + CView | 記事本、簡易編輯器 |
| MDI (多文檔介面) | CWinApp + CMDIFrameWnd + CMDIChildWnd + CDocument + CView | Word、Excel、VS IDE |
| 對話框應用 | CWinApp + CDialog | 工具箱、精靈、設定介面 |
| DLL (規則/擴展) | CWinApp 派生類 + 匯出函數/類 | 功能模組、外掛、控制項庫 |
| ActiveX 控制項 | COleControl + 事件/屬性/方法映射 | 網頁嵌入、VB/VC 容器使用 |
所有模板皆遵循文檔/視圖架構(除純對話框/DLL),實現「資料與顯示分離、多視圖同步更新」。
AFX_MODULE_STATE):管理 DLL/EXE 的資源鏈柄、類工廠、OLE 伺服器資訊,解決「DLL 中使用 MFC 資源」的跨模組問題。AFX_THREAD_STATE):保存當前執行緒的 m_pCurrentWinThread、m_hLockOut、m_pRoutingFrame 等,支援多執行緒 UI 操作。CWinApp::Run() 內部 PeekMessage + OnIdle 機制,支援背景任務、UI 更新。理解這些內部機制,能幫助您排查「資源找不到、跨執行緒存取失敗、DLL 卸載崩潰」等疑難雜症。
MFC 以「封裝 Win32、封裝應用概念、封裝 OLE、封裝資料存取」四大支柱,構建出一個高度內聚、低耦合、可擴充的應用程式框架。繼承體系提供擴充點,訊息映射解決動態繫結效率,文檔/視圖模板加速開發。掌握其設計哲學,不僅能事半功倍,更能在框架不足時「打破邊界、直達核心」。