在 MFC 中,點擊按鈕以 DoModal() 彈出子對話框時,若子對話框包含 CListCtrl 需初始化欄位,必須實例化子對話框類別而非基類 CDialog,並確保 OnInitDialog() 被正確呼叫。
void CMFCPaikeDlg::OnBnClickedOk() {
CDialogEx::OnOK(); // 這會關閉父對話框!
CDialog dlg(IDD_DIALOGCLASS); // 錯誤:用基類建立,無法呼叫子類 OnInitDialog
dlg.DoModal();
}
// 父對話框按鈕處理
void CMFCPaikeDlg::OnBnClickedOk() {
// 不要呼叫 CDialogEx::OnOK(),除非確要關閉父視窗
CClassEditDlg dlg; // 使用子對話框實際類別名
if (dlg.DoModal() == IDOK) {
// 使用者按確定後的處理
}
}
// 子對話框類別定義
class CClassEditDlg : public CDialogEx {
// ...
CListCtrl m_listCtrl;
virtual BOOL OnInitDialog() {
CDialogEx::OnInitDialog();
// 初始化 ListCtrl 欄位
m_listCtrl.InsertColumn(0, _T("ID"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(1, _T("Name"), LVCFMT_CENTER, 120);
// 可在此填充測試資料
return TRUE;
}
};
CClassEditDlg dlg; 而非 CDialog dlg(IDD...)。只有具體類別才有 OnInitDialog 覆寫與成員變數 m_listCtrl。CDialogEx::OnOK():那會關閉「父對話框」,導致程式流程異常。IDD,或在類別向導建立時自動關聯。DoDataExchange 中有 DDX_Control(pDX, IDC_LIST1, m_listCtrl);,否則控制項未綁定,操作會斷言失敗。DoModal():模態,阻塞父視窗,回傳 IDOK/IDCANCEL。Create(IDD, this) + ShowWindow(SW_SHOW):非模態,父視窗可繼續操作,需自行管理銷毀。正確實例化子對話框類別並確保 DDX 綁定,是 MFC 子視窗初始化控制項的核心步驟。