Win32中WM_INITDIALOG内调用SetDlgItemText无效的问题排查
解决Win32对话框SetDlgItemText找不到控件ID的问题
兄弟,你的问题根源其实很简单——在WM_INITDIALOG消息里调用GetActiveWindow()是错的!
当WM_INITDIALOG消息触发时,对话框还没有被激活成为活动窗口,这时候GetActiveWindow()返回的根本不是你当前这个对话框的句柄,而是之前的活动窗口句柄。你用这个错误的句柄去调用SetDlgItemText,当然找不到属于当前对话框的ID1004控件,所以GetLastError返回1421(控件ID未找到)就很正常了。
修正方案
直接用对话框过程的第一个参数hwnd作为SetDlgItemText的窗口句柄就好,这个参数就是当前对话框的合法句柄,在WM_INITDIALOG阶段已经完全有效了。去掉那个多余的dHandle = GetActiveWindow(),完全没必要。
修正后的WM_INITDIALOG代码片段:
case WM_INITDIALOG: MessageBox(NULL, "In InitDialog", 0, 0); // 直接使用对话框自身的hwnd,而非GetActiveWindow()的结果 SetDlgItemText(hwnd, 1004, "There are unsaved changes to \""); // 这里可以继续补全你的字符串,比如拼接具体文件名 char error[10]; sprintf_s(error, "%d", GetLastError()); MessageBox(NULL, error, 0, 0); return TRUE;
关于闪烁的问题
你把SetDlgItemText移到dHandle声明处(相当于每次消息处理都执行),这时候对话框已经激活,GetActiveWindow能拿到正确句柄,但因为每次消息循环都重复设置文本,自然会导致控件闪烁——这是错误的执行时机,正确的做法只在WM_INITDIALOG里设置一次初始文本就够了。
另外提一句,你原来的字符串("There are unsaved changes to \""))后面少了闭合的引号和文件名,记得补全,不然显示的文本会不完整。
内容的提问来源于stack exchange,提问作者Mizuna
相关产品推荐
相关产品推荐

