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

MFC 對話框開發精要:模態/非模態、CDialog 內部機制與訊息循環

     編輯:關於C語言

兩類對話框的本質差異

特性模態對話框非模態對話框
建立風格DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENUWS_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,必須釋放捕獲,否則模態對話框無法接收滑鼠輸入。

MFC 封裝:CDialog 核心實現

CDialog 繼承 CWnd,關鍵成員:

  • m_lpszTemplateName / m_hDialogTemplate:模板資源名稱或控制代碼。
  • DoModal():建立模態對話框,內部呼叫 ::DialogBoxIndirectParam,回傳 IDOK/IDCANCEL/-1。
  • Create():建立非模態對話框,呼叫 ::CreateDialogIndirectParam。
  • OnInitDialog():對應 WM_INITDIALOG,執行 DDX/DDV 資料交換與驗證,必須呼叫基類版本。
  • OnOK()/OnCancel():預設命令處理,模態下呼叫 EndDialog,非模態下呼叫 DestroyWindow(需覆寫)。

DDX/DDV 機制

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)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved