本講透過一個簡單的 MFC 應用程式範例,介紹「類別」與「物件」的核心觀念,分析 MFC 程式執行機制與基本類別階層結構,最後示範使用 MFC 應用程式精靈快速建立單一檔案應用程式專案。
在現代「物件導向」程式設計中,「類別」 是一種新的複雜資料型態:不同於 char、int、float 等基本型別,它不僅能封裝多種基本型別資料 (成員變數),還能封裝處理這些資料的函式 (成員函數)。
Ex_1_SimpMFC,按 [確定] 進入 [Win32 應用程式精靈]。
圖 1 Win32 應用程式精靈設定
SimpMFC,按 [開啟]。
#include
class CSimpApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
class CMainFrame : public CFrameWnd
{
public:
CMainFrame()
{
Create(NULL, _T("簡單 MFC 視窗"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 640, 480));
}
};
CSimpApp theApp;
BOOL CSimpApp::InitInstance()
{
m_pMainWnd = new CMainFrame;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
m_pMainWnd->MessageBox(_T("你好,歡迎進入 MFC 世界!"));
return TRUE;
}

圖 2 SimpMFC.cpp 檔案內容

圖 3 專案屬性頁設定 MFC 使用方式

圖 4 專案執行結果
#include :MFC 類別庫標頭檔。class 關鍵字定義類別,慣例以大寫 C 開頭命名 (如 CSimpApp)。public 為公開成員 (類別外可存取),private 為私有成員 (僅類別內部可存取),預設為 private。class 派生類別 : 繼承方式 基底類別。CSimpApp 繼承 CWinApp,CMainFrame 繼承 CFrameWnd。預設 public 繼承可使用基底類別所有公開成員。類別的多樣性:
virtual 宣告,如 InitInstance。基底與派生類別各自定義版本,系統依物件型別決定呼叫哪個版本。建構函式與解構函式:
CMainFrame()),物件建立時自動執行,用於初始化。無回傳型別。Create 函式建立視窗:參數依序為類別名、視窗標題、視窗樣式 (WS_OVERLAPPEDWINDOW 為標準視窗)、大小位置 (CRect)。~ (如 ~CMainFrame()),物件銷毀時自動執行,無參數無回傳值。成員函式定義位置:可在類別內定義,或類別外使用作用域運算子 :: (如 CSimpApp::InitInstance)。
關鍵全域指標與函式:
m_pMainWnd:MFC 全域指標,指向主視窗物件。MessageBox:CWnd 成員函式,彈出對話框顯示訊息。CSimpApp theApp 時,先呼叫基底類別 CWinApp 建構函式進行內部初始化。InitInstance():
m_pMainWnd = new CMainFrame; // 建立主視窗物件,呼叫建構函式 -> Create() 建立視窗
m_pMainWnd->ShowWindow(m_nCmdShow); // 顯示視窗
m_pMainWnd->UpdateWindow(); // 更新視窗
m_pMainWnd->MessageBox(...); // 彈出訊息框
return TRUE; // 表示初始化成功
InitInstance 返回後,呼叫基底類別 CWinApp::Run() 進入訊息迴圈:重複「接收訊息 → 轉發訊息」。訊息佇列為空時呼叫 OnIdle 處理背景工作;無訊息無背景工作則等待。CWinApp::ExitInstance() 執行清理工作。重點:MFC 利用類別「物件建立自動呼叫建構函式」特性,將傳統 WinMain 封裝在架構內部,開發者無需撰寫 WinMain。每個 MFC 應用程式有且只能有一個 CWinApp 派生類別與一個全域物件實例。

圖 5 MFC 類別基本階層結構 (箭頭指向基底類別)
| 類別 | 說明 |
|---|---|
CObject | 絕大多數 MFC 類別的根基底類別,提供動態記憶體管理、診斷、序列化支援 |
CCmdTarget | 訊息發送/等待/派遣,協調物件間運作 |
CWinThread | 執行緒控制 (建立、執行、終止、暫停) |
CWinApp | 應用程式主執行緒類別,繼承自 CWinThread |
CDocument | 文件類別,管理程式執行期間資料 |
CWnd | 通用視窗類別,提供 Windows 所有通用特性 |
CView | 視圖類別,存取文件並負責顯示 |
CFrameWnd | 框架視窗類別,繼承 CWnd,實作標準框架應用程式 |
CDialog | 對話框視窗控制 |
CMDIFrameWnd / CMDIChildWnd | 多文件應用程式主框架/子視窗 |
CMiniFrameWnd | 簡易框架視窗 (無最大化/最小化/系統選單),較少使用 |
實務上無需手寫上述程式碼,Visual C++ .NET 提供 MFC 應用程式精靈 (MFC AppWizard) 可零程式碼建立完整應用程式架構。
TextViewer,按 [確定]。
圖 6 應用程式類型設定
四種基本應用程式類型比較:
| 類型 | 特性 |
|---|---|
| 單一檔案 (SDI) | 類似記事本,一次只能開啟一個文件,複雜度適中,最常作為開發起點 |
| 多文件 (MDI) | 可同時開啟多個文件,功能豐富但需大量額外程式碼 |
| 多最上層文件 | 類似 MDI,但每個文件獨立顯示於桌面,各有工作列按鈕 (如 Office 2000/XP) |
| 以對話框為基礎 | 最簡單緊湊,無選單/工具列/狀態列,無法處理文件,開發除錯最快 |

圖 7 使用者介面功能設定

圖 8 進階功能設定

圖 9 產生的類別名稱與檔案設定

圖 10 TextViewer 專案執行結果
精靈除上述功能外,還支援資料庫、資源範本字串、複合文件等進階特性。使用 MFC 應用程式精靈可快速建立最常見的應用程式類型。精靈產生的各類別間存在緊密關聯,下一講將依據類別關聯機制,探討文件資料如何被讀取並顯示。