本講將深入探討對話框介面設計的完整流程與技巧,包含資源建立、控件佈局、類別創建,以及模態與非模態對話框的顯示機制差異。透過實作「背景設定」對話框,掌握 MFC 對話框開發的核心觀念。
對話框是 Windows 應用程式中最重要的使用者介面元素之一,透過按鈕、編輯框、列表框、下拉式方塊等控件與使用者互動。設計流程主要分為三階段:
IDD_DIALOG1,並建立含有 [確定]、[取消] 兩個按鈕的對話框範本,左側自動顯示工具箱視窗。
,使其固定停靠於開發環境左側。
圖 1 「加入資源」對話框

圖 2 對話框資源的屬性設定
推薦使用拖曳方式:在工具箱選取控件按住滑鼠不放,移至對話框所需位置鬆開。控件加入後,可透過下列方式精確佈局:
可啟用網格自動對齊。
圖 3 對話框資源編輯器介面

圖 4 對話框編輯器工具列
控件選取與主導控件觀念:
CSetDlg(慣例以大寫 C 開頭)。CDialog,確認 .h/.cpp 檔名無誤後按 [完成]。
圖 5 MFC 類別精靈設定
對話框分為兩種類型:
IDR_MAINFRAME 開啟選單資源。ID_FOMAT_SET。CViewerView 類別,於 OnFormatSet 函數撰寫顯示代碼:void CViewerView::OnFormatSet()
{
CSetDlg dlg;
if (dlg.DoModal() == IDOK)
{
MessageBox(_T("使用者按下確定"));
}
}

圖 6 模態對話框顯示代碼
關鍵說明:
DoModal() 為 CDialog 成員函數,負責模態對話框的顯示與結束。IDOK,按 [取消] 或關閉視窗回傳 IDCANCEL。ViewerView.h 加入 #include "SetDlg.h"。
圖 7 加入 CSetDlg 類別標頭檔

圖 8 模態對話框顯示結果(尚未加入控件)
非模態對話框與模態的關鍵差異在於記憶體管理與結束方式:
| 特性 | 模態對話框 | 非模態對話框 |
|---|---|---|
| 記憶體配置 | 系統自動配置,結束時自動釋放 | 開發者需自行配置與釋放 |
| 結束函數 | CDialog::EndDialog | CWnd::DestroyWindow |
實作步驟:
CSetDlg,於屬性視窗點選 [覆寫] 按鈕,加入 OnOK 與 OnCancel 覆寫。void CSetDlg::OnOK()
{
UpdateData(TRUE); // 確認輸入資料有效
DestroyWindow(); // 銷毀視窗
}
void CSetDlg::OnCancel()
{
DestroyWindow();
}

圖 9 加入 OnOK 函數覆寫

圖 10 非模態對話框結束代碼
CViewerView 加入成員指標 CSetDlg* m_pSetDlg。CViewerView 解構函數中刪除指標:CViewerView::~CViewerView()
{
if (m_pSetDlg) delete m_pSetDlg;
}

圖 11 解構函數中加入刪除代碼
OnFormatSet 以非模態方式建立並顯示對話框:void CViewerView::OnFormatSet()
{
if (!m_pSetDlg)
{
m_pSetDlg = new CSetDlg(this);
m_pSetDlg->Create(IDD_DIALOG1, this);
}
m_pSetDlg->ShowWindow(SW_SHOW);
}

圖 12 非模態顯示的 OnFormatSet 修改代碼
執行程式,外觀與模態對話框相同,但使用者可自由切換主視窗操作。下一講將討論如何取得非模態對話框中的使用者輸入資料。