最標準的方式是向主視窗發送 WM_CLOSE 訊息,觸發 CWnd::OnClose,讓使用者有機會決定是否儲存資料:
AfxGetMainWnd()->SendMessage(WM_CLOSE);
若需依視窗標題關閉特定應用程式,可封裝輔助函式:
void TerminateWindow(LPCTSTR pszCaption) {
CWnd* pWnd = CWnd::FindWindow(NULL, pszCaption);
if (pWnd) pWnd->SendMessage(WM_CLOSE);
}
注意:FindWindow 依賴視窗標題,若標題動態變更(如記事本開啟不同檔案)則失效。更穩健的做法是列舉系統工作清單或使用程序 ID 比對。
MFC 以同一 CDialog 衍生類支援模式與無模式,但生命週期管理截然不同:
OnOK/OnCancel,改呼叫 DestroyWindow() 而非 EndDialog()。PostNcDestroy 執行 delete this,釋放 C++ 物件(無模式對話框建立函式立即返回,呼叫端無法得知何時刪除)。Create() 而非 DoModal(),並以 new 配置物件於堆積上。void CMainFrame::OnSampleDialog() {
CSampleDialog* pDlg = new CSampleDialog;
ASSERT_VALID(pDlg);
BOOL bResult = pDlg->Create(IDD_DIALOG_SAMPLE);
ASSERT(bResult);
}
void CSampleDialog::OnOK() {
if (!UpdateData(TRUE)) return;
DestroyWindow();
}
void CSampleDialog::OnCancel() { DestroyWindow(); }
void CSampleDialog::PostNcDestroy() { delete this; }
覆寫 PreCreateWindow,移除 FWS_ADDTOTITLE 風格位:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
cs.style &= ~FWS_ADDTOTITLE;
return CMDIFrameWnd::PreCreateWindow(cs);
}
同理,關閉 MDI 子視窗的 FWS_ADDTOTITLE 後,可自行呼叫 SetWindowText 設定自訂標題。
MFC 預設以子視窗形式建立,控制 ID 固定:
AFX_IDW_STATUS_BARAFX_IDW_TOOLBARCStatusBar* pStatus = (CStatusBar*)GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar* pTool = (CToolBar*)GetDescendantWindow(AFX_IDW_TOOLBAR);
取得指標後可動態調整樣式、按鈕、窗格文字等。