在 IE Web 对话框窗口中自动化 HTML 文档? [英] Automating the HTML document in an IE web dialog window?

查看:17
本文介绍了在 IE Web 对话框窗口中自动化 HTML 文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

发布这个问题我可以为像我这样需要解决这个问题的人提供一个完整的例子......

Posting this question do I can provide a full example for anyone like me who needed to figure this out...

有时在自动化 IE 时,您可能会遇到一个需要与之交互的弹出对话框:我在这里专门讨论 IE 特定的模态对话框,并使用 showModalDialog

Occasionally when automating IE you may be faced with a pop-up dialog which you need to interact with: I'm specifically talking here about the modal dialog which is IE-specific, and opened using showModalDialog

https://msdn.microsoft.com/en-us/library/ms536759(v=vs.85).aspx

这些对话框不同于典型的弹出式"对话框或基于 window.open() 的对话框 - 尽管它们包含 HTML,但没有简单的方法来获取对所包含文档的引用对话框内.比如在windows shell下遍历windows就找不到这种类型的对话框.

These dialogs are different from the typical "pop-over" dialogs or ones based on window.open() - although they contain HTML, there's no easy way to get a reference to the document contained within the dialog. For example iterating through the windows under the Windows shell does not find this type of dialog.

我认为一定有某种方法可以使用 Windows API 解决此问题,并且我通过 Google 找到了一堆相关内容,但没有完整且独立的示例.

I figured there must be some way to solve this problem using the Windows API, and I found a bunch of relevant pieces via Google, but no complete and self-contained example.

有关我如何解决特定用例的问题,请参阅我的回答 - 如果您需要类似的东西,应该很容易重复使用.

See my answer for how I solved my specific use case - should be easily re-used if you need something similar.

推荐答案

这是我的最终结果(抱歉没有包含我找到关键部分的各种链接 - 如果我能重新找到它们,稍后会添加)

Here's what I ended up with (apologies for not including the various links where I found the key parts - will add later if I can re-find them)

https://social.msdn.microsoft.com/Forums/en-US/baf3cb64-8858-4d2d-9d7b-eaee76919256/modify-the-code-obtained-from-the-internet-explorerserver-hwnd-handle?forum=vbgeneral

声明(如果您安装了 64 位 Office,则需要进行一些调整)

Declarations (if you have 64-bit Office installed you will need to make some adjustments)

Option Explicit

' Requires: VBA project reference to "Microsoft HTML Object Library"

Private Const SMTO_ABORTIFHUNG = &H2
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2

Private Type UUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4(0 To 7) As Byte
End Type

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
    (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
    (ByVal hWnd As Long) As Long

Private Declare Function GetWindow Lib "user32" _
    (ByVal hWnd As Long, ByVal wCmd As Long) As Long

Private Declare Function IsWindowVisible Lib "user32" _
    (ByVal hWnd As Long) As Boolean

Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
    (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

Private Declare Function RegisterWindowMessage Lib "user32" _
     Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long

Private Declare Function SendMessageTimeout Lib "user32" _
   Alias "SendMessageTimeoutA" ( _
   ByVal hWnd As Long, _
   ByVal msg As Long, _
   ByVal wParam As Long, _
   lParam As Any, _
   ByVal fuFlags As Long, _
   ByVal uTimeout As Long, _
   lpdwResult As Long) As Long

Private Declare Function ObjectFromLresult Lib "oleacc" ( _
   ByVal lResult As Long, _
   riid As UUID, _
   ByVal wParam As Long, _
   ppvObject As Any) As Long

示例用法:

'An example of how to use this approach - other subs below should not need adjusting
Sub DialogDemo()

    Const DLG_TITLE = "User Info -- Webpage Dialog" '<< the dialog title
    Dim doc As IHTMLDocument

    Set doc = GetIEDialogDocument(DLG_TITLE)

    If Not doc Is Nothing Then
        'Debug.Print doc.body.innerHTML
        doc.getElementById("password_id").Value = "password"
        doc.getElementById("Notes_id").Value = "notes go here"
        doc.getElementById("b_Ok_id").Click '<< click OK
    Else
        MsgBox "Dialog Window '" & DLG_TITLE & "' was not found!", vbOKOnly + vbExclamation
    End If
End Sub

'Given an IE dialog window title, find the window and return a reference
'   to the embedded HTML document object
Function GetIEDialogDocument(dialogTitle As String) As IHTMLDocument
    Dim lhWndP As Long, lhWndC As Long, doc As IHTMLDocument
    'find the IE dialog window given its title
    If GetHandleFromPartialCaption(lhWndP, dialogTitle) Then
        Debug.Print "Found dialog window - " & dialogTitle & "(" & TheClassName(lhWndP) & ")"
        lhWndC = GetWindow(lhWndP, GW_CHILD)  'Find Child
        If lhWndC > 0 Then
            If TheClassName(lhWndC) = "Internet Explorer_Server" Then
                Debug.Print , "getting the document..."
                Set doc = IEDOMFromhWnd(lhWndC)
            End If
        End If
    Else
        Debug.Print "Window '" & dialogTitle & "' not found!"
    End If
    Set GetIEDialogDocument = doc
End Function

' IEDOMFromhWnd
' Returns the IHTMLDocument interface from a WebBrowser window
' hWnd - Window handle of the control
Function IEDOMFromhWnd(ByVal hWnd As Long) As IHTMLDocument
    Dim IID_IHTMLDocument As UUID
    Dim hWndChild As Long
    Dim lRes As Long
    Dim lMsg As Long
    Dim hr As Long

    If hWnd <> 0 Then

        lMsg = RegisterWindowMessage("WM_HTML_GETOBJECT") ' Register the message
        SendMessageTimeout hWnd, lMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes ' Get the object pointer

        If lRes Then
            With IID_IHTMLDocument ' Initialize the interface ID
                .Data1 = &H626FC520
                .Data2 = &HA41E
                .Data3 = &H11CF
                .Data4(0) = &HA7
                .Data4(1) = &H31
                .Data4(2) = &H0
                .Data4(3) = &HA0
                .Data4(4) = &HC9
                .Data4(5) = &H8
                .Data4(6) = &H26
                .Data4(7) = &H37
            End With
            ' Get the object from lRes (note - returns the object via the last parameter)
            hr = ObjectFromLresult(lRes, IID_IHTMLDocument, 0, IEDOMFromhWnd)
        End If
   End If 'hWnd<>0
End Function

'utilty function for getting the classname given a window handle
Function TheClassName(lhWnd As Long)
    Dim strText As String, lngRet As Long
    strText = String$(100, Chr$(0))
    lngRet = GetClassName(lhWnd, strText, 100)
    TheClassName = Left$(strText, lngRet)
End Function

Private Function GetHandleFromPartialCaption(ByRef lWnd As Long, _
                                             ByVal sCaption As String) As Boolean
    Dim lhWndP As Long, sStr As String

    GetHandleFromPartialCaption = False
    lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW
    Do While lhWndP <> 0
        sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
        GetWindowText lhWndP, sStr, Len(sStr)
        sStr = Left$(sStr, Len(sStr) - 1)
        If Len(sStr) > 2 Then
            If UCase(sStr) Like "*ARG*" Then Debug.Print sStr
        End If
        If InStr(1, sStr, sCaption) > 0 Then
            GetHandleFromPartialCaption = True
            lWnd = lhWndP
            Exit Do
        End If
        lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
    Loop
End Function

这篇关于在 IE Web 对话框窗口中自动化 HTML 文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆