使用 AppWizard 選擇「Dialog based」即可快速產生以對話框為主視窗的 MFC 應用程式。本文解析產生的核心代碼結構:`CWinApp::InitInstance()` 中建立模態對話框、`DoModal()` 迴圈、返回值處理與 `return FALSE` 結束應用程式的機制。
AppWizard 產生的關鍵代碼
BOOL CMyApp::InitInstance() {
CMyDlg dlg; // 對話框物件(堆疊配置)
m_pMainWnd = &dlg; // 指定為主視窗
int nResponse = dlg.DoModal(); // 進入模態迴圈
if (nResponse == IDOK) {
// 使用者按「確定」處理
} else if (nResponse == IDCANCEL) {
// 使用者按「取消」或 Esc 關閉
}
return FALSE; // 關鍵:返回 FALSE 讓應用程式結束
}
關鍵點解析
- 堆疊配置對話框:`CMyDlg dlg` 為區域變數,`DoModal()` 返回後自動銷毀,無需手動 `delete`
- `m_pMainWnd` 指向對話框:讓 MFC 內部機制(如命令路由)正常運作
- `DoModal()` 內部流程:建立視窗 → `RunModalLoop()` 訊息泵 → 使用者關閉 → `EndDialog()` 返回 `IDOK`/`IDCANCEL`
- `return FALSE`:告訴 `CWinApp::Run()` 不進入主訊息迴圈,直接結束程式。若改為 `TRUE`,程式會繼續跑訊息迴圈,但主視窗已關閉,通常不符合預期
後續開發流程
- 資源編輯器設計對話框版面(拖放控制項、設定 Tab Order)
- ClassWizard 新增控制項變數(`DDX_*`)與訊息處理(`BN_CLICKED`、`EN_CHANGE` 等)
- 在對話框類別中實作業務邏輯
- 若需屬性表介面,可在 `InitInstance` 或按鈕處理中建立 `CPropertySheet`(模態/非模態均可)
常見變體
- 非模態主對話框:`Create()` + `ShowWindow(SW_SHOW)`,需在 `InitInstance` 返回 `TRUE` 進入訊息迴圈,並在 `OnCancel`/`OnOK` 中 `DestroyWindow()` + `PostQuitMessage(0)`
- 多對話框切換:隱藏當前、建立新對話框 `DoModal()`,或使用 `CPropertySheet` 頁面切換