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

Win32 開發入門(18):對話框進階技巧 - 參數傳遞與返回值獲取

     編輯:關於C++

模態對話框支援透過 DialogBoxParam 傳遞參數、透過 EndDialog 返回值。本文詳細實作雙向資料交換模式與記憶體管理注意事項。

技巧一:顯示對話框時傳遞參數

DialogBoxParam 原型


INT_PTR DialogBoxParam(
    HINSTANCE hInstance,
    LPCTSTR lpTemplateName,
    HWND hWndParent,
    DLGPROC lpDialogFunc,
    LPARAM dwInitParam  // 自訂參數,傳遞給 WM_INITDIALOG 的 lParam
);

呼叫端


// 傳遞字串指標 (需確保壽命覆蓋對話框存續期)
LPCWSTR paramText = L"Win32 程式好玩嗎?";
DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_DLG1), hWnd,
               (DLGPROC)DialogProcWithParam, (LPARAM)paramText);

對話框程序接收


INT_PTR CALLBACK DialogProcWithParam(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_INITDIALOG: {
        LPCWSTR received = (LPCWSTR)lParam;  // 從 lParam 取得參數
        HWND hDisplay = GetDlgItem(hDlg, IDC_STATIC_INFO);
        SetWindowText(hDisplay, received);
        return TRUE;  // 設定焦點由系統處理
    }
    // ... 其他訊息處理
    }
    return FALSE;
}

技巧二:關閉對話框時返回值

呼叫端接收返回值


// DialogBox 返回 EndDialog 的第二個參數
LPCWSTR returnData = (LPCWSTR)DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DLG2),
                                        hWnd, (DLGPROC)DialogProcWithReturn);
if (returnData) {
    wchar_t buffer[100];
    wcscpy(buffer, returnData);  // 複製內容(原指標可能失效)
    MessageBox(hWnd, buffer, L"對話框返回資料", MB_OK);
}

對話框程序返回


INT_PTR CALLBACK DialogProcWithReturn(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK) {
            HWND hEdit = GetDlgItem(hDlg, IDC_EDIT_INPUT);
            int len = GetWindowTextLength(hEdit);
            wchar_t* text = new wchar_t[len + 1];
            GetWindowText(hEdit, text, len + 1);
            EndDialog(hDlg, (INT_PTR)text);  // 返回動態分配指標
            return TRUE;
        } else if (LOWORD(wParam) == IDCANCEL) {
            EndDialog(hDlg, NULL);
            return TRUE;
        }
        break;
    }
    return FALSE;
}

記憶體管理關鍵點

方向資料來源壽命責任建議做法
傳入參數呼叫端呼叫端使用靜態/全域/堆疊緩衝區,或共享所有權智慧指標
返回值對話框呼叫端對話框 new 配置,呼叫端 delete[] 釋放;或複製內容後釋放

安全模式:複製而非傳遞指標


// 對話框內:複製到呼叫端提供的緩衝區
case IDOK: {
    HWND hEdit = GetDlgItem(hDlg, IDC_EDIT_INPUT);
    wchar_t* callerBuffer = (wchar_t*)GetWindowLongPtr(hDlg, DWLP_USER);
    GetWindowText(hEdit, callerBuffer, MAX_PATH);
    EndDialog(hDlg, IDOK);
    return TRUE;
}

// 呼叫端:
wchar_t buffer[MAX_PATH] = {0};
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)buffer);  // 傳遞緩衝區指標
DialogBoxParam(..., (LPARAM)buffer);  // 或用 DWLP_USER
// 直接使用 buffer

執行結果

非模態對話框差異

  • CreateDialogParam 建立,同樣支援 WM_INITDIALOG 參數傳遞
  • 無 EndDialog 返回值,需透過 PostMessage/SendMessage 回傳資料給主視窗
  • 主視窗需監聽自訂訊息 (如 WM_USER+1) 接收結果

常見錯誤

  1. 返回棧上緩衝區指標 → 對話框結束後記憶體無效
  2. 傳遞參數指標指向臨時物件 → 存取違規
  3. 忘記釋放對話框 new 的返回緩衝區 → 記憶體洩漏
  4. DialogBoxParam 最後參數型別錯誤 (需 LPARAM 寬度) → 64位元截斷
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved