在 MFC 開發中,對話框的數據交換與驗證(Dialog Data Exchange/Validation,簡稱 DDX/DDV)是連接界面控件與成員變量的核心機制。其核心思想在於建立「變量 ↔ 子窗口」的關聯,再透過 BOOL UpdateData(BOOL bSaveAndValidate = TRUE) 統一協調數據流向:
直接綁定控件對象(如 CButton、CEdit、CComboBox),可直接操作控件行為(啟用/禁用、設定字型、取得游標位置等),無需呼叫 GetDlgItem() 取得指標。
綁定資料型別(CString、int、UINT、float 等),自動完成「控件文字 ↔ 變量數值」的轉換,適合單純的資料存取。
僅在「數值型變量」綁定時生效。常見驗證宏:
| 變量型別 | 驗證宏 | 說明 |
|---|---|---|
CString | DDV_MaxChars / DDV_MinChars | 限制字串長度 |
UINT/int | DDV_MinMaxUInt / DDV_MinMaxInt | 限制數值範圍 |
float/double | DDV_MinMaxFloat / DDV_MinMaxDouble | 限制浮點數範圍 |
若驗證失敗,MFC 自動彈出訊息框並讓 UpdateData() 回傳 FALSE,焦點自動導向違規控件。

| 控件 ID | 綁定變量 | 型別/類別 | 用途 |
|---|---|---|---|
| IDC_CHECK_TEST | m_fCheck | BOOL (Value) | 記錄核取方塊勾選狀態 |
| IDC_RADIO_TEST_1 | m_iSel | int (Value) | 單選群組目前索引(0-based) |
| IDC_COMBO_TEST | m_szCombo | CString (Value) | 取得編輯區文字或選中項目 |
| IDC_EDIT_TEST | m_szEdit | CString (Value) | 一般文字輸入 |
// 對話框類頭文件片段
class CMyDlg : public CDialog
{
//{{AFX_DATA(CMyDlg)
BOOL m_fCheck;
int m_iSel;
CString m_szCombo;
CString m_szEdit;
//}}AFX_DATA
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支援
};
// 對話框類實作片段
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyDlg)
DDX_Check(pDX, IDC_CHECK_TEST, m_fCheck);
DDX_Radio(pDX, IDC_RADIO_TEST_1, m_iSel);
DDX_CBString(pDX, IDC_COMBO_TEST, m_szCombo);
DDX_Text(pDX, IDC_EDIT_TEST, m_szEdit);
//}}AFX_DATA_MAP
// DDV 驗證範例
DDV_MaxChars(pDX, m_szEdit, 50); // 最多 50 字
DDV_MinMaxInt(pDX, m_iSel, 0, 2); // 單選索引 0~2
}
DoDataExchange 加入 DDX_* 宏,ClassWizard 不會自動維護。OnOK(),先呼叫 UpdateData(),失敗則 return;成功再呼叫 CDialog::OnOK()。若需同時享有「數值自動轉換」與「控件精細操作」,可對同一控件建立兩個變量:
// 頭文件
CEdit m_ctlEdit; // Control 型別
CString m_strEdit; // Value 型別
// DoDataExchange
DDX_Control(pDX, IDC_EDIT_TEST, m_ctlEdit);
DDX_Text(pDX, IDC_EDIT_TEST, m_strEdit);
此時 m_ctlEdit.SetLimitText(20) 限制輸入長度,m_strEdit 自動同步內容。