使用SendMessage向另存为对话框发送文件名,点击保存仍采用默认值
问题原因
- 你使用
WM_SETTEXT消息直接修改编辑框文本时,Win32编辑控件默认不会向其父窗口(也就是另存为对话框)发送EN_CHANGE通知事件。 - 另存为对话框依赖该通知事件同步后台存储的文件名变量,仅修改控件显示内容但未触发通知的情况下,后台变量仍保留初始默认值,点击保存时就会读取旧值报错。
- 手动输入或
SendKeys输入时,每次按键操作都会自动触发EN_CHANGE通知,因此对话框可以正常同步最新文件名。
解决方案
在你发送WM_SETTEXT修改编辑框内容之后,主动向编辑框的父窗口发送EN_CHANGE通知即可,修改后的核心代码如下:
' 提前声明需要用到的常量、API和辅助函数 Public Const EN_CHANGE As Long = &H300 Public Const WM_COMMAND As Long = &H111 Declare Function GetDlgCtrlID Lib "user32.dll" (ByVal hWnd As Long) As Long Declare Function GetParent Lib "user32.dll" (ByVal hWnd As Long) As Long ' 拼接WM_COMMAND的wParam参数 Function MakeWParam(loWord As Integer, hiWord As Integer) As Long MakeWParam = (hiWord * &H10000) Or (loWord And &HFFFF&) End Function Sub TestSaveAs() Dim ParentHwnd As Long Dim ChildHwnd As Long Dim x As Integer Dim strText As String Dim lngRet As Long Dim filepath As String Dim ctrlID As Long ' 新增变量存储编辑框控件ID strText = String$(100, Chr$(0)) filepath = "test" ' 另存为窗口当前已打开 ParentHwnd = FindWindow(vbNullString, "Save project") ChildHwnd = FindWindowEx(ParentHwnd, 0&, vbNullString, vbNullString) For x = 1 To 10 ' 查找文件名/路径对应的编辑框 ChildHwnd = FindWindowEx(ChildHwnd, 0&, vbNullString, vbNullString) lngRet = GetClassName(ChildHwnd, strText, 100) If left$(strText, lngRet) = "Edit" Then SendMessage ChildHwnd, WM_SETTEXT, 0, ByVal filepath ' 更新编辑框显示内容 ' 新增:主动发送内容变更通知 ctrlID = GetDlgCtrlID(ChildHwnd) SendMessage GetParent(ChildHwnd), WM_COMMAND, MakeWParam(ctrlID, EN_CHANGE), ByVal ChildHwnd DoEvents ' 确保消息处理完成 Exit For End If Next x ChildHwnd = FindWindowEx(ParentHwnd, 0&, vbNullString, vbNullString) For x = 1 To 10 ' 查找&Save(保存)按钮 ChildHwnd = FindWindowEx(ParentHwnd, ChildHwnd, vbNullString, vbNullString) lngRet = GetWindowText(ChildHwnd, strText, 100) If left$(strText, lngRet) = "&Save" Then Debug.Print UpdateWindow(ChildHwnd) SendMessage ChildHwnd, BM_CLICK, 0, 0 ' 发送保存按钮点击消息 Exit For End If Next x End Sub
内容的提问来源于stack exchange,提问作者barrs
相关产品推荐
相关产品推荐

