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

Windows SDK 筆記(四):模式對話方塊核心機制與實作詳解

     編輯:關於VC++

模式對話方塊基本特性

對話方塊是依據模板資源建立的特殊視窗。系統完成大部分流程,使用者提供訊息處理函式,但無需將不關心的訊息交由預設處理函式——系統自動完成預設處理。

對話方塊訊息處理函式架構

對話方塊是系統定義的「視窗類別」,已有對應處理函式。使用者撰寫的處理函式是對系統函式的補充/嵌入,並非直接連接視窗。因此:

  • 不需調用「預設訊息處理函式」
  • 處理訊息時回傳 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;

模式對話方塊與程式資料互動

1. 初始化階段(WM_INITDIALOG)

從全域變數讀取初始值設定控制項狀態。

2. 關閉階段

  • 確定(變更生效):依控制項狀態更新全域變數,EndDialog 回傳成功值(如 TRUE)
  • 取消(變更捨棄):不保存結果,EndDialog 回傳取消值(如 FALSE)

3. 呼叫端根據回傳值回應

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

常見控制項通知訊息處理

控制項通知代碼觸發時機典型處理
ButtonBN_CLICKED使用者點擊執行對應命令
EditEN_CHANGE文字內容變更即時驗證/預覽
ComboBoxCBN_SELCHANGE選取項目變更更新相關 UI
ListBoxLBN_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);

關鍵差異總結:模式 vs 非模式

項目模式對話方塊非模式對話方塊
建立 APIDialogBoxCreateDialog
訊息迴路系統內建(阻塞)應用程式主迴路(需 IsDialogMessage)
關閉 APIEndDialogDestroyWindow
結果傳遞函式回傳值需自行設計機制
適用場景需立即回應的關鍵操作輔助性、持續開啟的面板
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved