DialogBox 建立的是「模式對話方塊」——必須關閉後才能操作其他視窗。對應的「非模式對話方塊」建立後不強制使用者立即回應,與其他視窗同時接受操作,行為類似普通視窗。
使用 CreateDialog 建立,可在 WinMain 建立主視窗後建立,保存對話方塊控制代碼備用:
hDlgModeless = CreateDialog(
hInstance,
TEXT("ColorScrDlg"), // 對話方塊模板
hwnd, // 擁有者視窗
ColorScrDlg); // 對話方塊訊息處理函式
模式對話方塊有內部訊息泵機制,非模式對話方塊則由 WinMain 訊息迴路驅動。但對話方塊對特定按鍵(Tab、Enter 導航)有特殊處理,因此訊息迴路中需先給對話方塊攔截訊息的機會:
while (GetMessage(&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
IsDialogMessage 若處理了對話方塊訊息回傳 TRUE,則不需再分派。
使用 DestroyWindow(hDlg) 銷毀。使用者關閉對話方塊時,處理函式收到 WM_CLOSE,調用 DestroyWindow 銷毀。
BOOL CALLBACK ColorScrDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
// 初始化控制項狀態
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
DestroyWindow(hDlg); // 非模式用 DestroyWindow
return TRUE;
}
break;
}
return FALSE; // 未處理訊息交由系統預設處理
}
| 特性 | 模式對話方塊 | 非模式對話方塊 |
|---|---|---|
| 建立函式 | DialogBox / DialogBoxParam | CreateDialog / CreateDialogParam |
| 訊息迴路 | 內建訊息泵(阻塞) | 共用主訊息迴路(非阻塞) |
| 父視窗互動 | 阻塞父視窗 | 父視窗可繼續操作 |
| 關閉方式 | EndDialog | DestroyWindow |
| 回傳值處理 | DialogBox 回傳值 | 需自行機制傳遞結果 |
| 訊息迴路整合 | 自動處理 | 需在主迴路呼叫 IsDialogMessage |
非模式對話方塊無 EndDialog 回傳值機制,資料交換建議: