MFC 應用程式的退出過程是一個精心編排的級聯銷毀流程:使用者動作觸發命令 → 主視窗接收 WM_CLOSE → 文件/視圖/框架視窗依序關閉 → 發送 WM_QUIT 退出訊息迴路 → 物件析構釋放資源。本文詳細追蹤 SDI/MDI 架構下的關閉序列、虛擬函數調用鏈與關鍵清理邏輯。
WM_CLOSE 給主框架視窗。CWinApp::OnAppExit() 預設實現:m_pMainWnd->SendMessage(WM_CLOSE)。處理 SDI 主視窗、MDI 主框架、MDI 子視窗三種情況(圖 6-1):

m_lpfnCloseProc(列印預覽等特殊模式回呼)。CWinApp::CloseAllDocuments 關閉所有文件 → 銷毀所有視窗 → 發送 WM_QUIT 結束程式。DestroyWindow)。
CDocument::SaveModified():檢查修改旗標 → 詢問使用者(是/否/取消) → 是則呼叫 OnSaveDocument 序列化存檔 → 重置修改旗標。CDocument::OnSaveDocument:開檔 → 建立寫入 CArchive → Serialize 輸出 → 關閉。CWinApp::SaveAllModified/CloseAllDocuments → CDocManager → CDocTemplate → CDocument::SaveModified/OnCloseDocument 逐層遍歷。CDocument::OnCloseDocument 流程(圖 6-2):透過視圖取得框架視窗指標 → 關閉/銷毀框架視窗 → 若 m_bAutoDelete 則刪除文件物件。

CWnd::DestroyWindow():呼叫 API ::DestroyWindow → 發送 WM_DESTROY/WM_NCDESTROY 給視窗及子視窗 → 清理選單、計時器。CMDIChildWnd::DestroyWindow():覆寫,改發 WM_MDIDESTROY 給 Client 視窗由其銷毀子視窗。CFrameWnd::OnDestroy():銷毀工具列視窗 → 重置選單 → 若為主視窗通知 WinHelp 關閉 → 呼叫基類。CMDIFrameWnd::OnDestroy():調整 Client 邊框 → 呼叫基類(此時工具列列表為空)。CView::OnDestroy():若為作用中視圖則呼叫 SetActiveView 失活 → 基類處理。CWnd::OnNcDestroy():
1. 若為執行緒主視窗且非 DLL → PostQuitMessage(WM_QUIT)
2. 若為作用中視窗 → 設為 NULL
3. 清理 ToolTip、呼叫 Default()、Unsubclass (Detach HWND)
4. 呼叫虛擬函數 PostNcDestroy()
CFrameWnd::PostNcDestroy() / CView::PostNcDestroy():delete this 銷毀 MFC 物件。CFrameWnd 從模組-執行緒狀態 m_frameList 移除自身、刪除 m_phWndDisable;CView 從文件視圖列表移除。WM_CLOSE → OnClose → 關閉文件 → OnCloseDocument 銷毀主視窗 → OnNcDestroy 發送 WM_QUIT → 程式結束。
WM_CLOSE → OnClose → 關閉所有文件(銷毀所有 MDI 子視窗及視圖) → 主視窗仍在 → DestroyWindow 銷毀主視窗 → 發送 WM_QUIT。
OnCloseDocument 銷毀子視窗。主視窗存續,程式繼續執行。
WM_CLOSE 由框架視窗處理,委派給文件/視圖架構。WM_DESTROY 清理資源,WM_NCDESTROY 執行最終釋放與 delete this。m_bAutoDelete 機制確保 MFC 物件隨視窗銷毀自動釋放,符合 RAII 原則。