Results 1 to 8 of 8

Thread: IE Automation - Getting Window Handles

  1. #1

    Thread Starter
    New Member
    Join Date
    Nov 2016
    Posts
    15

    IE Automation - Getting Window Handles

    Hello Experts,

    I've had some recent success automating IE with VBA. I've been able to login to Crystal Reports, fill in some form information, and submit a request for a report. Once the report is generated, Crystal Reports gives you the option to export the report to pdf, rtf, etc. formats. This is where my problem starts. When I click the Export button, it creates a new dialog. From what I've read, I should be able to get the handle of this new dialog window, via FindWindow, FindWindowEx, and use SendMessage to send commands to the new dialog.
    This is the code I have so far:

    Code:
        Dim lhWndC As Long
        Dim lhWndP As Long
        Dim sStr As String
    
    ' Get the handle of the parent window.
        lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW
        If (lhWndP <> 0) Then
    ' Cycle through all the child windows.
            Do While lhWndP <> 0
                sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
                GetWindowText lhWndP, sStr, Len(sStr)
                sStr = Left$(sStr, Len(sStr) - 1)
    ' Once we find the child window with the title we're looking for...
                If InStr(1, sStr, "Export Report") > 0 Then
    ' Get the handle of the Export Report window.
                    lhWndC = FindWindowEx(lhWndP, ByVal 0&, "BrowserFrameGripperClass", vbNullString)
                    If (lhWndC <> 0) Then
    ' Put the Export Report window to the foreground.
                        lngRet = SetForegroundWindow(lhWndC)
                        SendMessage lhWndC , BM_CLICK, 0, vbNullString
                     Else
                         MsgBox "Handle of OK button not found."
                     End If
                 Else
                     MsgBox "Handle of Export Report window not found."
                 End If
              End If
              lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
            Loop
        Else
            MsgBox "Handle of parent window not found."
        End If
    Here is a screenshot of what uuSpy tells me:
    Name:  uuSpy.jpg
Views: 1851
Size:  53.4 KB

    Here is a screenshot of the Export Report dialog:
    Name:  Export Report.jpg
Views: 1124
Size:  59.6 KB

    I'm actually trying to pick one of the choices from the drop down list. But I can't tell from uuSpy how to access that object. I don't have access to Spy++ as I do not have Visual Studio. Any thoughts on how to better communicate with this Export Report dialog would be greatly appreciated.

    TMMc

  2. #2
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: IE Automation - Getting Window Handles

    is the export report window a dialog or an explorer window?
    if it is a dialog your code may not continue to run until the dialog is closed, so all your findwindow code will be suspended until the dialog is closed, when it will not find the window anyway


    lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW
    as this gives no hint as to which window to find i would sort of guess it would find the windows desktop, but that would need to be tested

    i can not make any suggestions, without being able to test against that, or a very similar, web page
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  3. #3

    Thread Starter
    New Member
    Join Date
    Nov 2016
    Posts
    15

    Re: IE Automation - Getting Window Handles

    Hi westconn1,

    The Export Report window is a child of the main IE window. When I click on the export button in Crystal Reports (which is running in the main IE window), the Export Report window is spawned.
    I am 99% sure I am successfully getting the handle of both the parent and child window. The reason I say that is because when this line is executed:

    Code:
    lngRet = SetForegroundWindow(lhWndC)
    the Export Report window is brought to the foreground. In order for that to work, the handle of the child window would have to be correct. But from that point, I am not sure how to control the objects in the Export Report window. My understanding is that each object within the Export Report window has its own unique handle. But I don't know how to get those handles. I thought uuSpy would give me that handle information but, as best as I can tell, it is not giving me any handle information for objects in the Export Report window.

    TMMc

  4. #4
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: IE Automation - Getting Window Handles

    the Export Report window is brought to the foreground
    OK, i see that, possibly you could just find that window by passing the window caption to findwindow, but if it is working...........

    is not giving me any handle information for objects in the Export Report window.
    from the image it appears that the information for many objects is there, though i can not see there the combobox you are looking for, but it may be further down the list
    you would need to use findwindowex to loop all the child windows to find one matching the criteria for the combobox, then you may need to find the child windows of the combobox to find an edit window etc, the final solution may vary depending on OS and IE versions

    can you not just automate the internet explorer object in the new (export report) window, then work with the html elements?
    if it was a dialog you would be stuck with findwindow, but an internet explorer window should give you the ability to work with the html elements
    Last edited by westconn1; Feb 2nd, 2017 at 03:19 PM.
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  5. #5

    Thread Starter
    New Member
    Join Date
    Nov 2016
    Posts
    15

    Re: IE Automation - Getting Window Handles

    from the image it appears that the information for many objects is there, though i can not see there the combobox you are looking for, but it may be further down the list
    The image shows the information for all the objects. There is nothing further down in the list.

    can you not just automate the internet explorer object in the new (export report) window, then work with the html elements?
    I had originally read that you cannot control the html elements of a child window. That's why I started down the road of findwindow/findwindowex.
    This is the html for the export report window. If you can suggest a way to get at the html elements, I'm all ears.

    Code:
    <HTML><HEAD><TITLE>Export Report</TITLE>
    <link rel='stylesheet' type='text/css' href='/crystalreportviewers115/css/default.css'><script type='text/javascript' src='/crystalreportviewers115/js/exportdialog.js'></script><script type='text/javascript'>function checkValuesAndSubmit() {if (document.forms['dlgform'].isRange != null && document.forms['dlgform'].isRange[1].checked) {if (!isValidNumber(document.forms['dlgform'].from.value) || !isValidNumber(document.forms['dlgform'].to.value) || (parseInt(document.forms['dlgform'].from.value, 10) > parseInt(document.forms['dlgform'].to.value, 10))) {alert('The page range value(s) are incorrect.  Please enter a valid page range.');return;} } if (document.forms['dlgform'].exportformat != null && document.forms['dlgform'].exportformat.value == '') {alert('Please select an Export format from the list.');return;} 	window.opener.document.getElementById('CrystalViewerCrystalForm').target = '_self';
    	window.opener.CrystalEvent('CrystalViewer','tb=crexport&text=' + document.forms['dlgform'].exportformat.value + '&range=' + document.forms['dlgform'].isRange[1].checked + '&from=' + document.forms['dlgform'].from.value + '&to=' + document.forms['dlgform'].to.value);window.close();
    } </script></head><body class='crexportpage' bottommargin='5' topmargin='5' onload='checkDisableRange();'><form name='dlgform'><TABLE cellspacing='0' cellpadding='0' width='100%' height='100%' valign='bottom' halign='center' border='0'><TR><TD align='left'><table width='100%' border='0'><tr><td width='35%'><span class='crexportmessage'><label for='exportformatlist'>File Format:</label></span></td><td align='left' width='65%' class='crexportselect'><select id='exportformatlist' class='crexportselect' name='exportformat' onchange='checkDisableRange();'><option selected value='CrystalReports'>Crystal Reports (RPT)</option><option value='PDF'>Adobe Acrobat (PDF)</option><option value='MSExcel'>Microsoft Excel 97-2000 (XLS)</option><option value='RecordToMSExcel'>Microsoft Excel 97-2000 - Data Only (XLS)</option><option value='MSWord'>Microsoft Word (RTF)</option><option value='EditableRTF'>Microsoft Word - Editable (RTF)</option><option value='RTF'>Rich Text Format (RTF)</option></select></td></tr></table></TD></TR><TR><TD><hr class='crexportruler'></TD></TR><TR><TD align='left'><table width='100%' border='0'><tr><td width='35%'><span class='crexportmessage'>Page Range:</span></td><td width='65%' align='left'><input type='radio' id='radio1' checked name='isRange' value='all' onclick='return toggleRangeFields(this);'/><span class='crexportmessage'><label for='radio1'>All</label></span></td></tr><tr><td rowspan='2'>&nbsp;</td><td align='left'><input type='radio' id='radio2' name='isRange' value='selection' onclick='return toggleRangeFields(this);'/><span class='crexportmessage'><label for='radio2'>Pages:</label></span></td></tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class='crexportmessage'><label for='from'>From:</label></span>&nbsp;&nbsp;<input class='crexporttextbox' type='text' width='20' size='6' maxlength='6' name='from' value='1'>&nbsp;&nbsp;<span class='crexportmessage'><label for='to'>To:</label></span>&nbsp;&nbsp;<input class='crexporttextbox' type='text' width='20' size='6' maxlength='6' name='to' value='1'></td></tr></table></TD></TR><TR><TD><hr class='crexportruler'></TD></TR><TR valign='top'><TD align='right'><input class='crexportbutton' type='button' value='OK' onclick='checkValuesAndSubmit();'/>&nbsp;&nbsp;<input class='crexportbutton' type='button' value='Cancel' onclick='window.close();'/></TD></TR></TABLE></form></body></html>
    In the mean time, I can keep working at using findwindowex to loop all the child windows to find one matching the criteria for the combobox,

  6. #6
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: IE Automation - Getting Window Handles

    I had originally read that you cannot control the html elements of a child window.
    one way or another, you can automate all internet explorer windows that are open

    as i have not seen the code to open the child window, i can not make a suggestion based on navigation_complete event, or if you even are receiving events, but you can enumerate all shell windows, to find the specific window, which in most cases, will be the last window opened, like
    Code:
    set sh = createobject("shell.application")
    set wb = sh.windows(sh.windows.count - 1)
    you can then work with the html elements within the document
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  7. #7

    Thread Starter
    New Member
    Join Date
    Nov 2016
    Posts
    15

    Re: IE Automation - Getting Window Handles

    as i have not seen the code to open the child window, i can not make a suggestion based on navigation_complete event,
    Here is the code that opens the child window.

    Code:
    Dim Window          As MSHTML.IHTMLWindow2
    
        Set Window = ieDoc.Frames(0).Frames(0).Frames(1).Frames(1)
    ' Press the 'Export this report' button.
        Call Window.execScript("doExport('exportdlg');", "JavaScript")
    Based on this code snippet, does your previous code suggestion still apply?

    Code:
    set sh = createobject("shell.application")
    set wb = sh.windows(sh.windows.count - 1)
    If it does apply, can you explain what this code would do?

  8. #8

    Thread Starter
    New Member
    Join Date
    Nov 2016
    Posts
    15

    Re: IE Automation - Getting Window Handles

    westconn1, once again your great suggestion lead me in the right direction. Here is the code that lets me select the file format from the dropdown list and click OK, all within the child window.. What I didn't realize until I tried your code is that it let me work with the HTML elements within the document. Thanks so much for your help!

    Code:
        Dim sh          As Object
        Dim wb          As Object
        Dim ieDoc       As MSHTML.HTMLDocument
        Dim elems       As MSHTML.IHTMLElementCollection
        Dim e           As MSHTML.IHTMLElement
    
        Set sh = CreateObject("shell.application")
        Set wb = sh.Windows(sh.Windows.Count - 1)
        Set ieDoc = wb.Document
    ' Select the report format from the dropdown list. Index is 0-based.
        ieDoc.getElementById("exportformatlist").selectedIndex = 3
    
    ' Click the OK button.
        With ieDoc
            Set elems = .getElementsByTagName("input")
            For Each e In elems
                If ((e.getAttribute("className") = "crexportbutton") And _
                    e.Value = "OK") Then
                    e.Click
                    Exit For
                End If
            Next e
        End With
    
     ' Clean up.   
        Set sh = Nothing
        Set wb = Nothing
        Set ieDoc = Nothing

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width