单击资源管理器下载弹出窗口上的保存按钮

时间:2019-08-19 23:01:13

标签: html vb.net internet-explorer

我正在尝试自动从网页获取文件。它将打开“保存下载”窗口,其中包含3个通常的选择(“打开”,“保存”和“取消”)。我正在尝试单击“保存”按钮,但无法使其正常工作。我什至试图从Spy ++获取&Save句柄并在执行ClickButton之前插入句柄指针,以确保我拥有正确的句柄指针,但仍然一无所获。

除了SendMessage(WindowHandle, BM_CLICK, 0, IntPtr.Zero)

之外,其他所有功能都正常
Sub ClickButton(ByVal WindowHandle As IntPtr)
    'SendMessageW(WindowHandle, WM_ACTIVATE, New IntPtr(WA_ACTIVE), IntPtr.Zero) I've tried several flavors of this ClickButton and no effect! 
    'SendMessageW(WindowHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero)
    SendMessage(WindowHandle, BM_CLICK, 0, IntPtr.Zero)
End Sub


Sub LookForAndCloseIEPopup()
    'get a handle to any popup window associated with the main form (as is a popup window
    'displayed by the Web browser control)...
    Dim ptrDialogWindow As IntPtr = GetWindow(xAsIntPtr, GW_ENABLEDPOPUP)
    Dim text2 = GetWindowText(xAsIntPtr)
    If text2.Contains("File Download") Then
        'xAsIntPtr = hWnd
        'LookForAndCloseIEPopup() '(GetWindowText(hwnd, text, Int16.MaxValue))
    End If

    Debug.Print(GetWindowText(ptrDialogWindow) & "TEXT:=" & Text2 & vbCrLf)
    'if the popup window is one displayed by the browser, then send the close message to the window...
    If text2.Contains("File Download") Then ClosePopup(ptrDialogWindow)

End Sub

Sub ClosePopup(ByVal WindowHandle As IntPtr)

    Dim clsChildHandles As ArrayList = GetChildWindowHandles(WindowHandle)
    Dim teststr As String
    Dim prthandleint As Long
    'look through all of the child handles of the window for an "OK" button (this method 
    'can also be used to gather more specific information about the dialog itself, such as 
    'the message being displayed)...
    For Each ptrHandle As IntPtr In clsChildHandles
        'if the OK button is found, click it...
        teststr = GetWindowText(ptrHandle)
        prthandleint = ptrHandle
        'ptrHandle = &H002A0B7E    !!! I even tried putting the &Save handle which I got from Spy++ with the same result! 
        Debug.Print(GetWindowText(ptrHandle) & " = Child TEXT:   len=" & teststr.Length & "handle = " & prthandleint & vbCrLf)

        If teststr.Contains("&Save") Then
            ClickButton(ptrHandle)  'This part works fine as I get here
            Exit For
        Else
            Debug.Print(GetWindowText(ptrHandle) & " = Child TEXT:   len=" & vbCrLf)
        End If
    Next

End Sub

Const WM_GETTEXT As Long = &HD
Const WM_GETTEXTLENGTH As Long = &HE
Const GW_ENABLEDPOPUP As Long = 6
Const BM_CLICK As Long = &HF5&
Const GW_CHILD As Long = 5
Const GW_HWNDNEXT As Long = 2
Const WM_ACTIVATE As Integer = &H6
Const WA_ACTIVE As Integer = &H1
'function to retrieve the popup window associated with the form, as well as to find the child windows of the popup...
Private Declare Auto Function GetWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal uCmd As Integer) As IntPtr
<DllImport("user32.dll", EntryPoint:="SendMessageW")>
Private Shared Function SendMessageW(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
'sendmessage overload that is used to send messages to the button on the dialog window...
Private Declare Auto Function SendMessage Lib "user32.dll" Alias "SendMessage" (ByVal hWnd As IntPtr, ByVal Msg As Integer,
ByVal wParam As Integer, ByRef lParam As IntPtr) As IntPtr

'sendmessage overloads used to retrieve the window text...
Private Declare Auto Function SendMessageA Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer,
ByVal wParam As IntPtr, ByRef lParam As IntPtr) As IntPtr
<DllImport("User32.dll", CharSet:=CharSet.Auto, EntryPoint:="SendMessage")> Public Shared Function SendMessageString(ByVal hwnd As IntPtr,
ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As IntPtr
End Function
Function GetChildWindowHandles(ByVal ParentWindowHandle As IntPtr) As ArrayList

    Dim b As Boolean
    Dim ptrChild As IntPtr
    Dim clsRet As New ArrayList
    'ParentWindowHandle = IntPtr(xAsIntPtr)
    'get first child handle...
    ptrChild = GetChildWindowHandle(xAsIntPtr)

    Do Until ptrChild.Equals(IntPtr.Zero)
        'add to collection of handles...
        clsRet.Add(ptrChild)
        'get next child...
        ptrChild = GetNextWindowHandle(ptrChild)

    Loop

    'return...
    Return clsRet

End Function

Function GetChildWindowHandle(ByVal ParentWindowHandle As IntPtr) As IntPtr
    Return GetWindow(ParentWindowHandle, GW_CHILD)
End Function

Function GetNextWindowHandle(ByVal CurrentWindowhandle As IntPtr) As IntPtr
    Return GetWindow(CurrentWindowhandle, GW_HWNDNEXT)
End Function

'this function returns the text of the window, used so that we can confirm that we have the right dialog window...
Function GetWindowText(ByVal WindowHandle As IntPtr) As String

    Dim ptrRet As IntPtr
    Dim ptrLength As IntPtr

    'get length for buffer...
    ptrLength = SendMessageA(WindowHandle, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)

    'create buffer for return value...
    Dim sb As New System.Text.StringBuilder(ptrLength.ToInt32 + 1)

    'get window text...
    ptrRet = SendMessageString(WindowHandle, WM_GETTEXT, ptrLength.ToInt32 + 1, sb)

    'get return value...
    Return sb.ToString

End Function

在调试输出窗口中,我看到&Save的值被捕获,并且代码按预期工作,直到ClickButton试图以无响应的方式执行。

1 个答案:

答案 0 :(得分:0)

亲自找到解决方案!

需要将setactiveWindow放在第一位!

    SetActiveWindow(xAsIntPtr)
    SendMessageW(WindowHandle, WM_ACTIVATE, New IntPtr(WA_ACTIVE), IntPtr.Zero)
    SendMessageW(WindowHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero)

Pete