| 特性 | 模態對話框 | 非模態對話框 |
|---|---|---|
| 建立風格 | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_POPUP | WS_CAPTION | WS_BORDER | WS_SYSMENU |
| 顯示行為 | 無視 WS_VISIBLE,必定顯示 | 需 WS_VISIBLE 或呼叫 ShowWindow |
| 擁有者視窗 | 自動停用,直到對話框結束 | 不停用,可自由切換焦點 |
| 訊息循環 | Windows 內建獨立循環,攔截鍵盤導航 | 共用主訊息循環,需呼叫 IsDialogMessage |
| 結束方式 | EndDialog(nResult) 返回值給呼叫者 | DestroyWindow(),無返回值 |
| 典型用途 | 設定對話框、警告、需阻塞的互動 | 工具視窗、尋找/取代、模擬面板 |
Windows 為模態對話框建立獨立訊息泵:
WM_INITDIALOG、WM_SETFONT 初始化。WM_QUIT 重新張貼到主佇列。WM_ENTERIDLE 給擁有者(可做背景工作,但必須快速讓出控制權)。WM_CANCELMODE,必須釋放捕獲,否則模態對話框無法接收滑鼠輸入。CDialog 核心實現CDialog 繼承 CWnd,關鍵成員:
m_lpszTemplateName / m_hDialogTemplate:模板資源名稱或控制代碼。DoModal():建立模態對話框,內部呼叫 ::DialogBoxIndirectParam,回傳 IDOK/IDCANCEL/-1。Create():建立非模態對話框,呼叫 ::CreateDialogIndirectParam。OnInitDialog():對應 WM_INITDIALOG,執行 DDX/DDV 資料交換與驗證,必須呼叫基類版本。OnOK()/OnCancel():預設命令處理,模態下呼叫 EndDialog,非模態下呼叫 DestroyWindow(需覆寫)。void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
DDV_MaxChars(pDX, m_strName, 20);
DDX_Check(pDX, IDC_CHECK_OPTION, m_bOption);
}
UpdateData(TRUE) 從控制項讀取資料(觸發 DDV 驗證),UpdateData(FALSE) 將資料寫入控制項。
PostNcDestroy 中 delete this(需設 m_bAutoDelete = TRUE 或手動管理)。OnInitDialog 返回 TRUE 讓系統設定焦點,返回 FALSE 表示自行設定焦點(需手動 SetFocus)。