首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

MFC 應用程式退出機制深度解析:從 WM_CLOSE 到物件銷毀全流程

     編輯:關於VC++

MFC 應用程式的退出過程是一個精心編排的級聯銷毀流程:使用者動作觸發命令 → 主視窗接收 WM_CLOSE → 文件/視圖/框架視窗依序關閉 → 發送 WM_QUIT 退出訊息迴路 → 物件析構釋放資源。本文詳細追蹤 SDI/MDI 架構下的關閉序列、虛擬函數調用鏈與關鍵清理邏輯。

一、 退出觸發入口:ID_APP_EXIT 與 WM_CLOSE

  • 使用者點選「檔案/結束」或主視窗關閉鈕,最終發送 WM_CLOSE 給主框架視窗。
  • CWinApp::OnAppExit() 預設實現:m_pMainWnd->SendMessage(WM_CLOSE)。

二、 CFrameWnd::OnClose — 關閉邏輯中樞

處理 SDI 主視窗、MDI 主框架、MDI 子視窗三種情況(圖 6-1):

  1. 檢查 m_lpfnCloseProc(列印預覽等特殊模式回呼)。
  2. 主視窗關閉:呼叫 CWinApp::CloseAllDocuments 關閉所有文件 → 銷毀所有視窗 → 發送 WM_QUIT 結束程式。
  3. MDI 子視窗關閉:
    • 若文件僅由該視窗顯示 → 關閉文件與視窗。
    • 若文件還有其他視圖 → 僅銷毀該子視窗(DestroyWindow)。

三、 文件存檔與關閉協作鏈

  • CDocument::SaveModified():檢查修改旗標 → 詢問使用者(是/否/取消) → 是則呼叫 OnSaveDocument 序列化存檔 → 重置修改旗標。
  • CDocument::OnSaveDocument:開檔 → 建立寫入 CArchive → Serialize 輸出 → 關閉。
  • CWinApp::SaveAllModified/CloseAllDocuments → CDocManager → CDocTemplate → CDocument::SaveModified/OnCloseDocument 逐層遍歷。

CDocument::OnCloseDocument 流程(圖 6-2):透過視圖取得框架視窗指標 → 關閉/銷毀框架視窗 → 若 m_bAutoDelete 則刪除文件物件。

四、 視窗銷毀雙階段:WM_DESTROY 與 WM_NCDESTROY

1. DestroyWindow 虛擬函數

  • CWnd::DestroyWindow():呼叫 API ::DestroyWindow → 發送 WM_DESTROY/WM_NCDESTROY 給視窗及子視窗 → 清理選單、計時器。
  • CMDIChildWnd::DestroyWindow():覆寫,改發 WM_MDIDESTROY 給 Client 視窗由其銷毀子視窗。

2. OnDestroy 處理器

  • CFrameWnd::OnDestroy():銷毀工具列視窗 → 重置選單 → 若為主視窗通知 WinHelp 關閉 → 呼叫基類。
  • CMDIFrameWnd::OnDestroy():調整 Client 邊框 → 呼叫基類(此時工具列列表為空)。
  • CView::OnDestroy():若為作用中視圖則呼叫 SetActiveView 失活 → 基類處理。

3. OnNcDestroy — 最後清理與 PostNcDestroy

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 從文件視圖列表移除。

五、 SDI / MDI 三種關閉場景完整流程

1. SDI 主視窗關閉

WM_CLOSE → OnClose → 關閉文件 → OnCloseDocument 銷毀主視窗 → OnNcDestroy 發送 WM_QUIT → 程式結束。

2. MDI 主框架關閉

WM_CLOSE → OnClose → 關閉所有文件(銷毀所有 MDI 子視窗及視圖) → 主視窗仍在 → DestroyWindow 銷毀主視窗 → 發送 WM_QUIT。

3. MDI 子視窗 (文件框架) 關閉

非主視窗分支:檢查文件是否有其他視圖 → 有則僅銷毀子視窗;無則關閉文件 → OnCloseDocument 銷毀子視窗。主視窗存續,程式繼續執行。

六、 關鍵設計模式總結

  • 命令路由:WM_CLOSE 由框架視窗處理,委派給文件/視圖架構。
  • 雙階段銷毀:WM_DESTROY 清理資源,WM_NCDESTROY 執行最終釋放與 delete this。
  • 自動記憶體管理:m_bAutoDelete 機制確保 MFC 物件隨視窗銷毀自動釋放,符合 RAII 原則。
  • 文件-視圖分離:文件關閉不一定銷毀文件物件(多視圖共享時),視圖銷毀不一定關閉文件。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved