模態對話框支援透過 DialogBoxParam 傳遞參數、透過 EndDialog 返回值。本文詳細實作雙向資料交換模式與記憶體管理注意事項。
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) 接收結果new 的返回緩衝區 → 記憶體洩漏DialogBoxParam 最後參數型別錯誤 (需 LPARAM 寬度) → 64位元截斷