對話方塊是依據模板資源建立的特殊視窗。系統完成大部分流程,使用者提供訊息處理函式,但無需將不關心的訊息交由預設處理函式——系統自動完成預設處理。
對話方塊是系統定義的「視窗類別」,已有對應處理函式。使用者撰寫的處理函式是對系統函式的補充/嵌入,並非直接連接視窗。因此:
TRUE 表示已處理FALSE,系統再調用預設處理BOOL(非 LRESULT)BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE; // 回傳 TRUE 表示已處理
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg, 0); // 使用 EndDialog 關閉
return TRUE;
}
break;
}
return FALSE; // 未處理訊息交由系統預設處理
}
使用 DialogBox 函式:
INT_PTR DialogBox(
HINSTANCE hInstance, // 模組控制代碼
LPCTSTR lpTemplate, // 對話方塊模板
HWND hWndParent, // 擁有者視窗
DLGPROC lpDialogFunc); // 對話方塊處理函式
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_ABOUT:
DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDlgProc);
break;
}
return 0;
從全域變數讀取初始值設定控制項狀態。
EndDialog 回傳成功值(如 TRUE)EndDialog 回傳取消值(如 FALSE)if (DialogBox(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc))
InvalidateRect(hwnd, NULL, TRUE); // 回傳 TRUE 時重繪視窗
IDD_ABOUT DIALOGEX 0, 0, 200, 150
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "關於"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "確定", IDOK, 80, 120, 50, 14
PUSHBUTTON "取消", IDCANCEL, 140, 120, 50, 14
LTEXT "版本 1.0", IDC_STATIC, 20, 20, 160, 8
LTEXT "Copyright © 2024", IDC_STATIC, 20, 35, 160, 8
END
| 控制項 | 通知代碼 | 觸發時機 | 典型處理 |
|---|---|---|---|
| Button | BN_CLICKED | 使用者點擊 | 執行對應命令 |
| Edit | EN_CHANGE | 文字內容變更 | 即時驗證/預覽 |
| ComboBox | CBN_SELCHANGE | 選取項目變更 | 更新相關 UI |
| ListBox | LBN_DBLCLK | 雙擊項目 | 啟動編輯/檢視 |
| 所有 | WM_CTLCOLORDLG | 繪製背景前 | 自訂對話方塊背景色 |
複雜設定對話方塊建議使用 PropertySheet:
PROPSHEETPAGE psp = { sizeof(psp) };
psp.dwFlags = PSP_USETITLE;
psp.hInstance = hInstance;
psp.pszTemplate = MAKEINTRESOURCE(IDD_PAGE1);
psp.pfnDlgProc = Page1DlgProc;
psp.pszTitle = TEXT("一般");
PROPSHEETHEADER psh = { sizeof(psh) };
psh.dwFlags = PSH_PROPSHEETPAGE;
psh.hwndParent = hwnd;
psh.hInstance = hInstance;
psh.pszCaption = TEXT("設定");
psh.nPages = 1;
psh.ppsp = &psp;
PropertySheet(&psh);
| 項目 | 模式對話方塊 | 非模式對話方塊 |
|---|---|---|
| 建立 API | DialogBox | CreateDialog |
| 訊息迴路 | 系統內建(阻塞) | 應用程式主迴路(需 IsDialogMessage) |
| 關閉 API | EndDialog | DestroyWindow |
| 結果傳遞 | 函式回傳值 | 需自行設計機制 |
| 適用場景 | 需立即回應的關鍵操作 | 輔助性、持續開啟的面板 |