首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Windows SDK 筆記(五):非模式對話方塊完整實作指南

     編輯:關於VC++

非模式對話方塊核心概念

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;  // 未處理訊息交由系統預設處理
}

模式 vs 非模式對話方塊關鍵差異對照

特性模式對話方塊非模式對話方塊
建立函式DialogBox / DialogBoxParamCreateDialog / CreateDialogParam
訊息迴路內建訊息泵(阻塞)共用主訊息迴路(非阻塞)
父視窗互動阻塞父視窗父視窗可繼續操作
關閉方式EndDialogDestroyWindow
回傳值處理DialogBox 回傳值需自行機制傳遞結果
訊息迴路整合自動處理需在主迴路呼叫 IsDialogMessage

常見應用場景

  • 尋找/取代對話方塊:編輯器中持續開啟,不阻塞編輯操作
  • 工具面板/屬性視窗:IDE 側邊欄面板
  • 進度顯示視窗:長時間操作的進度回饋,允許使用者取消
  • 浮動工具列:可拖曳定位的功能面板

資料交換最佳實務

非模式對話方塊無 EndDialog 回傳值機制,資料交換建議:

  1. 使用共用資料結構或全域變數
  2. 對話方塊關閉前主動更新共用資料
  3. 或註冊回呼函式/發送自訂訊息通知主視窗
  4. 避免使用模態對話方塊的回傳值模式
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved