Reflection Terminal Emulator - Integration with IE
-
03-07-2019 - |
Question
I'm trying to implement some integration between a legacy app running in the Reflection Terminal Emulator and a browser-based app running in IE.
I'm using Host Initiated Scripts so that maintenance and deployment issues are isolated to the legacy app. All scripts will be generated in the legacy app and transmitted to Reflection using escape sequences.
I am currently able to:
- Launch IE
- Set options such as hiding toolbars
- Navigate to a URL
- Transmit status info back to the legacy app
- Wait for a "close" signal from the legacy app
- Close IE
Here's VBA code to do that:
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = CreateObject("InternetExplorer.Application")
objIE.ToolBar = false
objIE.Navigate("http://www.google.com/")
objIE.Visible = true
Session.Transmit "OK" & CR
Session.WaitForString "CLOSE", 0, rcAllowKeystrokes
objIE.Quit
End Sub
The problem with this is that the script continues to run until it gets the close command from the legacy app.
What I want to do is use one script to launch the browser, and another to either close it or re-use it for another URL. However, I haven't been able to find a way to save my reference to IE across script calls. Declaring objIE as Global outside Sub Main didn't help. The Session object does persist across script calls, but it doesn't appear to have a property that I can use for this purpose. (Session does have a UserData property, but that's a String, not an Object.)
Here's an example of what I'd like to do:
Script 1 - Open IE & Leave it Open:
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = CreateObject("InternetExplorer.Application")
objIE.ToolBar = false
objIE.Navigate("http://www.google.com/")
objIE.Visible = true
Session.Transmit "OK" & CR
End Sub
Script 2 - Send original IE window to a new URL
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = FindOriginalIE()
objIE.Navigate("http://www.stackoverflow.com/")
Session.Transmit "OK" & CR
End Sub
Script 3 - Close IE
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = FindOriginalIE()
objIE.Quit
Session.Transmit "OK" & CR
End Sub
The part that I can't figure out is how to implement the FindOriginalIE() function used in Scripts 2 and 3.
I tried using GetObject() instead of CreateObject(), but that got me nowhere. GetObject() won't open a new IE window, or find an existing one. I suspect this is because I'm running under Citrix, but I'm not sure.
My only leads right now are to try using IE's hWND to reconnect to the original window, or to use DDE instead of OLE. I haven't had much luck with either of those however, mainly because of a lack of documentation.
So, my questions are:
- Is what I'm trying to do possible using OLE? That is, is there a way to persist my handle to IE across host initiated script calls?
- Should I expect GetObject() to work, or is that a dead end?
- Is it possible to use the Win32 API in a host initiated script to re-connect to IE using hWND?
Any links to related articles, sample code, or other insights are greatly appreciated.
Solution
AFAIK GetObject is just not supported for the InternetExplorer object. However this is not the end:) Among many other ways you can yank it out of the windows collection of shell32. For the example code (adapted from code in the link above) to work you need to set a reference to the following:
- Microsoft Internet Controls
- Microsoft HTML Object Library
- Microsoft Shell Controls and Automation
Public Sub RunMeFirst()
Dim objIE As SHDocVw.InternetExplorer
Set objIE = New SHDocVw.InternetExplorer
objIE.Visible = True
objIE.navigate "http://www.google.com/"
Do Until objIE.readyState = READYSTATE_COMPLETE
DoEvents
Loop
End Sub
Public Sub RunMeSecond()
Dim objIE As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
Set objIE = GetIEByURL("http://www.google.com/")
Set doc = objIE.document
MsgBox doc.body.innerText
End Sub
Private Function GetIEByURL(ByVal URL As String) As SHDocVw.InternetExplorer
Dim objShell As Shell32.Shell
Dim objExplorer As Shell32.ShellFolderView
Dim obj As Object
Set objShell = New Shell
For Each obj In objShell.Windows
If TypeOf obj Is SHDocVw.InternetExplorer Then
If StrComp(obj.LocationURL, URL, vbTextCompare) = 0& Then
Exit For
End If
End If
Next obj
Set GetIEByURL = obj
End Function
I think it might be worth discussing what you are trying to accomplish though. Roboting IE is a pretty kludgey approach (of which I am often guilty), but there might be a better, less resource intensive way.