行,今天就来唠唠我捣鼓DialogBoxParam
这个东西的经历。平时咱们做界面,弹个框让用户输点啥或者确认个事儿,那太常见。一般情况下,搞个对话框资源,然后用DialogBox
函数弹出来就完事,简单直接。
但有一次,我遇到个情况稍微麻烦点儿。我需要在对话框弹出来的时候,就给它传点初始数据进去。比如,弹出一个编辑框,我希望它打开的时候里面已经有默认的文字,这个文字不是写死在资源里的,而是我程序运行到那一步动态决定的。用DialogBox
就不太方便直接传这种动态数据。
为啥要用DialogBoxParam
这时候我就琢磨,得找个能在创建对话框时就把参数塞进去的办法。翻翻资料,也问问老鸟,就发现DialogBoxParam
。这函数名字就带个"Param",顾名思义,就是能带参数的。它跟DialogBox
哥俩长得挺像,用法也大差不差,关键的区别就在于它多一个参数,专门用来传递你想传给对话框的数据。
实际动手过程
那具体咋用?也不复杂,跟我一步步来:
- 先准备好对话框资源:这个跟用
DialogBox
一样,你得先在资源编辑器里画好你的对话框,给它一个ID,比如叫IDD_MYDIALOG
。 - 写对话框处理函数(Dialog Procedure):这个函数是核心,用来处理对话框上的各种消息,比如按钮点击、文本输入啥的。函数签名大概长这样:
INT_PTR CALLBACK MyDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
。 - 调用DialogBoxParam:在需要弹出对话框的地方,不再调用
DialogBox
,而是调用DialogBoxParam
。像这样:DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), hwndParent, MyDialogProc, myData);
hInstance
:程序的实例句柄,这个好说。MAKEINTRESOURCE(IDD_MYDIALOG)
:就是你的对话框资源ID。hwndParent
:父窗口句柄,对话框会显示在它前面,并且通常会“锁住”父窗口。MyDialogProc
:就是你上面写的那个对话框处理函数。myData
: 这就是重点!你想传递给对话框的数据就放在这里。它可以是任何你想传的值,通常是个指针,指向一个结构体或者就是一个简单的数值。类型是LPARAM
,就是个长整型,足够放指针。
- 在对话框处理函数里接收数据: 光传过去还不行,对话框得能收到。关键就在处理
WM_INITDIALOG
这个消息。当对话框刚创建、还没显示出来的时候,系统会给你的MyDialogProc
发送这个消息。这个时候,你通过DialogBoxParam
传递的那个myData
,就放在lParam
参数里!所以在
MyDialogProc
里面,你得这样写:switch (message) {
case WM_INITDIALOG:
// 把lParam转回你原来的数据类型
MyDataType pData = (MyDataType)lParam;
// 现在你可以用pData里的数据来初始化对话框控件
// 比如设置文本框内容:
// SetDlgItemText(hwndDlg, IDC_EDIT1, pData->initialText);
// 或者选中某个复选框:
// CheckDlgButton(hwndDlg, IDC_CHECKBOX1, pData->isChecked ? BST_CHECKED : BST_UNCHECKED);
// 这里还可以把这个数据存起来,比如用SetWindowLongPtr存到窗口用户数据里,方便以后用
// SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pData);
return (INT_PTR)TRUE; // 表示你处理消息,焦点会按默认设置
// ... 处理其他消息,比如按钮点击 WM_COMMAND ...
case WM_COMMAND:
if (LOWORD(wParam) == IDOK LOWORD(wParam) == IDCANCEL) {
// 用户点确定或取消,关闭对话框
EndDialog(hwndDlg, LOWORD(wParam)); // EndDialog会结束对话框,并把值返回给DialogBoxParam的调用处
return (INT_PTR)TRUE;
break;
// ...
return (INT_PTR)FALSE; // 其他消息没处理,返回FALSE
特别注意:在
WM_INITDIALOG
里,拿到lParam
传来的数据后,赶紧用它来设置对话框控件的初始状态。这正是用DialogBoxParam
的目的。
收尾工作
对话框用完,通常是用户点击“确定”或“取消”按钮。在对应的WM_COMMAND
消息处理里,调用EndDialog
函数关闭对话框。EndDialog
的第二个参数会作为DialogBoxParam
函数的返回值,这样调用它的地方就能知道用户是点确定还是取消,或者传回什么结果。
就这样,通过DialogBoxParam
和在WM_INITDIALOG
里接收lParam
,我就实现动态数据传递到新对话框的需求。一开始可能觉得绕,但搞清楚流程后,用起来还是挺顺手的。特别是需要给对话框“预设”点东西的时候,这招确实好使。