|
-
Feb 1st, 2017, 08:29 PM
#1
Thread Starter
New Member
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:

Here is a screenshot of the Export Report dialog:

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
-
Feb 2nd, 2017, 04:49 AM
#2
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
-
Feb 2nd, 2017, 08:40 AM
#3
Thread Starter
New Member
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
-
Feb 2nd, 2017, 03:16 PM
#4
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
-
Feb 3rd, 2017, 03:30 PM
#5
Thread Starter
New Member
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'> </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> <span class='crexportmessage'><label for='from'>From:</label></span> <input class='crexporttextbox' type='text' width='20' size='6' maxlength='6' name='from' value='1'> <span class='crexportmessage'><label for='to'>To:</label></span> <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();'/> <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,
-
Feb 4th, 2017, 05:30 AM
#6
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
-
Feb 6th, 2017, 11:00 AM
#7
Thread Starter
New Member
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?
-
Feb 6th, 2017, 02:39 PM
#8
Thread Starter
New Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|