VBA中使用FindWindowEx函数如何向网页表单中的多个文本框中的某一个文本框发送消息

使用FindWindowEx函数如何向网页表单中的多个文本框中的某一个文本框发送消息
问题描述: 我需要向网页表单窗口中某一个文本框模拟输入手机号码以及回车键, 其中模拟输入手机号码以及回车键的功能已经调试成功, 问题是: 网页表单中有多个文本框, 我的代码中使用了 hwndTextBox = FindWindowEx(hwndAddressBar, 0, "Edit", vbNullString) , FindWindowEx()函数执行后的返回值=0, 这句代码始终调试不通过, 现在将全部VBA 核定代码上传, 请大家给予帮助指点. ]

Sub TypeNumericStringInIE(ByVal s As String)
    
Dim hwndIE As Long
Dim hwndAddressBar As Long
Dim hwndTextBox As Long
    
Dim i As Integer


' 使用FindWindow函数查找IE窗口句柄
hwndIE = FindWindow("IEFrame", vbNullString)

If hwndIE <> 0 Then
 ' 使用FindWindowEx函数查找IE地址栏文本框句柄 
hwndAddressBar = FindWindowEx(hwndIE, 0, "Frame Tab", vbNullString)       
hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "TabWindowClass", vbNullString)
hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "Shell DocObject View", vbNullString)
hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "internet Explorer_Server", vbNullString)



**‘ 这一句是问题关键所在, 网页中的文本框有很多个, 我需要向其中一个具体的文本框发送消息, 这一句代码执行后, hwndTextBox返回值总是0 ’  
hwndTextBox = FindWindowEx(hwndAddressBar, 0, "Edit", vbNullString)      **
       
        
If hwndAddressBar <> 0 Then 

 ' 使用SendMessage函数发送WM_SETFOCUS消息,将文本框获取焦点
            
SendMessage hwndTextBox, WM_SETFOCUS, 0, 0 
            
 ' 循环模拟键盘输入数字              
For i = 1 To Len(s)                
Select Case Mid(s, i, 1)                   
Case "0"                        
keybd_event VK_NUMPAD0, 0, 0, 0                        
keybd_event VK_NUMPAD0, 0, KEYEVENTF_KEYUP, 0                   
Case "1"                        
keybd_event VK_NUMPAD1, 0, 0, 0                        
1 keybd_event VK_NUMPAD1, 0, KEYEVENTF_KEYUP, 0                    
Case "2"                        
keybd_event VK_NUMPAD2, 0, 0, 0                        
keybd_event VK_NUMPAD2, 0, KEYEVENTF_KEYUP, 0
                    
Case "3"                        
keybd_event VK_NUMPAD3, 0, 0, 0                        
keybd_event VK_NUMPAD3, 0, KEYEVENTF_KEYUP, 0
                    
Case "4"                        
keybd_event VK_NUMPAD4, 0, 0, 0                        
keybd_event VK_NUMPAD4, 0, KEYEVENTF_KEYUP, 0
                    
Case "5"                        
keybd_event VK_NUMPAD5, 0, 0, 0                        
keybd_event VK_NUMPAD5, 0, KEYEVENTF_KEYUP, 0
                    
Case "6"                        
keybd_event VK_NUMPAD6, 0, 0, 0                        
keybd_event VK_NUMPAD6, 0, KEYEVENTF_KEYUP, 0
                    
Case "7"                        
keybd_event VK_NUMPAD7, 0, 0, 0                        
keybd_event VK_NUMPAD7, 0, KEYEVENTF_KEYUP, 0
                   
Case "8"                        
keybd_event VK_NUMPAD8, 0, 0, 0                        
keybd_event VK_NUMPAD8, 0, KEYEVENTF_KEYUP, 0
                    
Case "9"                        
keybd_event VK_NUMPAD9, 0, 0, 0                        
keybd_event VK_NUMPAD9, 0, KEYEVENTF_KEYUP, 0
                
End Select            
Next i
                        
' 使用SendMessage函数发送WM_CHAR消息,模拟按下回车键
SendMessage hwndTextBox, WM_CHAR, VK_RETURN, 0
        
End If      
End If   
End Sub

引用chatgpt部分指引作答:
问题可能出在使用FindWindowEx函数时指定的参数不正确。根据您的描述,您希望找到网页表单中的一个文本框并向其发送消息。在网页中,文本框通常被标记为"INPUT"标签,并且其类名通常为"Edit"。但是在使用FindWindowEx函数时,类名参数应该是窗口类名而不是标签名。

解决这个问题的方法是使用Inspect工具来查看网页表单中文本框的类名,然后将该类名作为参数传递给FindWindowEx函数。以下是修改后的代码示例:

Sub TypeNumericStringInIE(ByVal s As String)
    Dim hwndIE As Long
    Dim hwndAddressBar As Long
    Dim hwndTextBox As Long
    Dim i As Integer

    ' 使用FindWindow函数查找IE窗口句柄
    hwndIE = FindWindow("IEFrame", vbNullString)
    
    If hwndIE <> 0 Then
        ' 使用FindWindowEx函数查找IE地址栏文本框句柄 
        hwndAddressBar = FindWindowEx(hwndIE, 0, "Frame Tab", vbNullString)
        hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "TabWindowClass", vbNullString)
        hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "Shell DocObject View", vbNullString)
        hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "Internet Explorer_Server", vbNullString)
        
        If hwndAddressBar <> 0 Then
            ' 使用FindWindowEx函数查找文本框句柄
            hwndTextBox = FindWindowEx(hwndAddressBar, 0, "EDIT", vbNullString)
            
            If hwndTextBox <> 0 Then
                ' 使用SendMessage函数发送WM_SETFOCUS消息,将文本框获取焦点
                SendMessage hwndTextBox, WM_SETFOCUS, 0, 0
                
                ' 循环模拟键盘输入数字
                For i = 1 To Len(s)
                    Dim keyCode As Integer
                    keyCode = Asc(Mid(s, i, 1)) + 48 ' 将数字字符转换为相应的键码
                    keybd_event keyCode, 0, 0, 0
                    keybd_event keyCode, 0, KEYEVENTF_KEYUP, 0
                Next i
                
                ' 使用SendMessage函数发送WM_CHAR消息,模拟按下回车键
                SendMessage hwndTextBox, WM_CHAR, VK_RETURN, 0
            End If
        End If
    End If
End Sub

上述代码假设文本框的类名为"EDIT",如果实际情况不是这样,请使用Inspect工具查看网页表单中文本框的类名,并将其替换为正确的类名。另外,代码中的VK_NUMPAD0至VK_NUMPAD9键码的计算方式也做了相应的修改,以确保输入正确的数字字符。

请尝试使用修改后的代码,并确保Inspect工具中的类名和窗口层次结构是正确的,这样您应该能够向网页表单中的特定文本框发送消息。

补充说明: 在excel 2010 中调试上述代码, hwndTextBox = FindWindowEx(hwndAddressBar, 0, "Edit", vbNullString) , FindWindowEx()函数执行后的返回值=0, 这句代码始终调试不通过, 求教各位大神!

img

这是我用inspect 工具,同时打开了网页表单窗口,选择了其中一个文本框, Inspect显示了很多代码, 我没有用过Inspect 工具,不知道哪一个才是FindWindowEx()函数的可选参数, (类名ID) ,请大家指点

我还是看不大明白, ID 究竟是多少? 求各位大神告知!!! 不胜感激.
这个网页表单好像对手机号码 这个文本框做了设置, 必须要键盘鼠标输入号码,好像是Jaugle网页, 我在哪里查到过, 记不得具体名称了, 我现在的代码就卡在找不到文本框,后面的模拟键盘鼠标输入数字串, 都能调试出来, 实在是想不出来了,求各位大神告知!

hwndTextBox = FindWindowEx(hwndAddressBar, 0, "UIA_EditControlTypeId(OXC354)", vbNullString) ,返回值还是=0

img

hwndTextBox = FindWindowEx(hwndAddressBar, 0, "2A.102AE.2.1168A", vbNullString) 返回值=0
hwndTextBox = FindWindowEx(hwndAddressBar, 0, "5848", vbNullString) 返回值=0
不管是用了RuntimeId, 还是processID, 返回值都为0 , 好苦恼!

img

今天代码做了如下调整,



Sub TypeNumericStringInIE2(ByVal s As String)
    
     Dim inputElement As Object
     Dim i As Integer
     
        
     Set inputElement = mDocument.forms("Sy01FormIdJb").Item("aac067")
         inputElement.Focus
  

 ' 模拟按键
    For i = 1 To Len(s)
    Call mDocument.parentWindow.execScript("document.activeElement.value = document.activeElement.value + """ & Mid$(s, i, 1) & """;", "JavaScript")
    Next i
     


     '这3句话都报错了
     Call mDocument.parentWindow.execScript("var e = new Event('keypress'); ")
     Call mDocument.parentWindow.execScript("e.keyCode = 13; e.which = 13;")
     Call mDocument.parentWindow.execScript("this.dispatchEvent(e);"'或者是
     mDocument.parentWindow.execScript "var e = new Event('keypress'); e.keyCode = 13; e.which = 13; this.dispatchEvent(e);"  这句话调试没有通过,报错了




 ' 关闭IE对象
   ' ie.Quit
    Set inputElement = Nothing
End Sub

模拟键盘输入数字已经成功了. ,现在就剩下向网页表单文本框发送回车键代码没有通过了.
mDocument.parentWindow.execScript "var e = new Event('keypress'); e.keyCode = 13; e.which = 13; this.dispatchEvent(e);"
求各位大神指点!

经过各位大神的耐心指点,不吝赐教, 终于攻克了向网页表单某个文本框模拟键盘输入,对文本框.value赋值的难题, 现在产生一个新问题, 网页表单数据全部赋值完毕后, 点击保存按钮,无法保存成功. 点击保存按钮的 “检查元素” ,出现的代码窗口中提示: q.handle vendor.js(2) ; 我问了工程师,在保存时,对输入数据的合理性、逻辑性进行了检验设置, 因为我的网页表单的数据全部是VBA 编程自动提取赋值的, 可能跟保存按钮中javascript 基本代码做的检验设置有抵触, 导致无法走完, 所以无法保存网页表单.

img

img

img

求:各位大神帮忙看看js 代码, 该在哪里修改下, 能跳过这种检验,直接提交网页表单数据.

尝试以下步骤:

1.识别要向其发送消息的文本框的唯一特征,例如其名称、类或ID。

2.使用Spy++工具检查web窗体窗口的层次结构,并找到文本框的句柄(HWND)。

3.将FindWindowEx函数中的“Edit”参数替换为文本框的唯一标识符,例如其类名或ID。

4.修改SendMessage功能,将消息发送到您在步骤2中找到的特定文本框的句柄。

以下是修改后的代码示例:

Sub TypeNumericStringInIE(ByVal s As String)

Dim hwndIE As Long
Dim hwndAddressBar As Long
Dim hwndTextBox As Long

Dim i As Integer
 
 
' 使用FindWindow函数查找IE窗口句柄
hwndIE = FindWindow("IEFrame", vbNullString)
 
If hwndIE <> 0 Then
    ' 使用FindWindowEx函数查找IE地址栏文本框句柄 
    hwndAddressBar = FindWindowEx(hwndIE, 0, "Frame Tab", vbNullString)       
    hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "TabWindowClass", vbNullString)
    hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "Shell DocObject View", vbNullString)
    hwndAddressBar = FindWindowEx(hwndAddressBar, 0, "internet Explorer_Server", vbNullString)
     
    ' 根据文本框的类名或ID查找文本框句柄
    hwndTextBox = FindWindowEx(hwndAddressBar, 0, "input", "textbox_id")
       
    If hwndTextBox <> 0 Then 
 
        ' 使用SendMessage函数发送WM_SETFOCUS消息,将文本框获取焦点
        SendMessage hwndTextBox, WM_SETFOCUS, 0, 0 
       
        ' 循环模拟键盘输入数字              
        For i = 1 To Len(s)                
            Select Case Mid(s, i, 1)                   
                Case "0"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("0"), 0
                Case "1"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("1"), 0
                Case "2"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("2"), 0
                Case "3"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("3"), 0
                Case "4"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("4"), 0
                Case "5"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("5"), 0
                Case "6"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("6"), 0
                Case "7"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("7"), 0
                Case "8"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("8"), 0
                Case "9"                        
                    SendMessage hwndTextBox, WM_CHAR, Asc("9"), 0
            End Select            
        Next i
                            
        ' 使用SendMessage函数发送WM_KEYDOWN和WM_KEYUP消息模拟按下回车键
        SendMessage hwndTextBox, WM_KEYDOWN, VK_RETURN, 0
        SendMessage hwndTextBox, WM_KEYUP, VK_RETURN, 0
          
    End If      
End If 

End Sub
将“textbox_id”替换为要作为目标的文本框的实际id或类名。还要注意,现在使用SendMessage函数将WM_CHAR消息发送到特定的文本框句柄,而不是使用keybd_event函数来模拟输入。

基于ChatGpt Plus版参考回答:
问题出现在尝试使用FindWindowEx函数查找网页表单中的文本框句柄时。FindWindowEx函数的第二个参数是用于指定子窗口的类名或标识符,但您将其设置为0,这可能是导致无法找到正确句柄的原因。
在Excel 2010中,您可能无法直接使用FindWindowEx函数来访问网页表单中的文本框。FindWindowEx函数主要用于在Windows操作系统中查找窗口句柄,而不是在网页中查找表单元素。

如果您想在Excel VBA中自动填充网页表单,您可以尝试使用InternetExplorer对象来实现。下面是一个示例代码,演示如何使用InternetExplorer对象在Excel VBA中填充网页表单:

Sub FillWebForm()
    Dim ie As Object
    Dim doc As Object
    Dim form As Object
    Dim inputElement As Object
    
    ' 创建 InternetExplorer 对象
    Set ie = CreateObject("InternetExplorer.Application")
    
    ' 设置 IE 可见性
    ie.Visible = True
    
    ' 导航到网页
    ie.Navigate "http://example.com"
    
    ' 等待网页加载完成
    Do While ie.Busy Or ie.readyState <> 4
        DoEvents
    Loop
    
    ' 获取文档对象
    Set doc = ie.Document
    
    ' 根据表单名称或 ID 获取表单对象
    Set form = doc.forms("formName") ' 或者使用 form = doc.getElementById("formID")
    
    ' 根据元素名称或 ID 获取文本框对象,并填充值
    Set inputElement = form.elements("textBoxName") ' 或者使用 inputElement = doc.getElementById("textBoxID")
    inputElement.Value = "1234567890" ' 填充文本框的值
    
    ' 提交表单
    form.submit
    
    ' 关闭 IE
    ie.Quit
    Set ie = Nothing
End Sub

请注意,这段代码是基于 Internet Explorer 浏览器的,对于其他浏览器可能需要使用不同的方法。另外,使用自动化方式填充网页表单可能受到浏览器安全设置和自动化限制的限制,具体情况可能因浏览器版本和安全策略而异。

网页中的控件应该不是窗口,你可以用spy++察看下,应该看不到窗口句柄

根据您提供的代码,我看到您使用了FindWindowEx函数来查找网页表单中的文本框句柄。但是,您遇到的问题是无法获取到具体的文本框句柄,返回值总是0。

首先,确保您使用的窗口句柄是正确的,并且能够找到网页表单的父窗口句柄。这样才能正确使用FindWindowEx函数来查找子窗口。

其次,请确认您传递给FindWindowEx函数的参数是否正确。第三个参数应该是类名(Class Name)或者控件类型的名称,而不是"Edit"。因为在网页表单中,文本框的类名可能不是"Edit"。

您可以尝试使用Spy++等工具来查看网页表单窗口的结构和控件信息,获取正确的类名或控件类型名称,并将其作为参数传递给FindWindowEx函数。

另外,如果您使用的是Internet Explorer浏览器,可以考虑使用IE对象模型来操作网页表单,而不是通过窗口句柄和SendMessage函数。

综上所述,您可以按照以下步骤进行调试和解决问题:

  1. 确认窗口句柄和父窗口句柄是否正确。
  2. 使用Spy++等工具查看网页表单窗口的结构和控件信息,获取正确的类名或控件类型名称。
  3. 将正确的类名或控件类型名称作为参数传递给FindWindowEx函数。
  4. 确保您的代码在执行FindWindowEx函数之前,窗口和控件已经加载完成。
  5. 考虑使用IE对象模型来操作网页表单,以更直观和可靠的方式实现您的目标。

希望以上建议对您有帮助,祝您成功解决问题!