Since Microsoft released Service Pack 2 (and other security patches) for Windows XP, Internet Explorer blocks active content in HTML files. Greg Gerber, one of my readers notified me about that trouble - thanks Greg. After investigating the problem, I found out, that the script within my lokal HTML form is threaded in IE as active content and will be blocked. A WSH script, that tries to use some procedures from the HTML form, will fail. As a consequence, my HTML form samples used within my sample scripts (published in my WSH books) won't work anymore. But I found a way to modify my form samples to make it compatible with IE 6 and Win XP SP. So let's talk about the details.
(c) Günter Born, http://www.borncity.de
Warning: The material submitted as a newsletter comes AS-IS without any warranty of any kind. In no event shall the author be liable for damages and losses of any kind. The material discussed herein is copyrighted by the author. You get a free right to use it. This newsletter may be distribute freely as long as: a) the text remains intact and unmodified, b) a reference to the WSH Bazaar www.borncity.de is given and c) the newsletter is not shipped with other commercial material. If you like to ship the newsletter with CD-ROMs etc. please ask. Permission will be granted in normal cases, but I like to know where my material goes into.
What's the beef? Well, WSH doesn't support a GUI. That's a bit nasty, because WScript.Echo, PopUp and VBScript MsgBox statements are not really comfortable to display more than simple results. And only VBScript provides a primitiv user input dialog (inputbox statement). JScript users simply doesn't have anything to read a user input.
People who are intending to write scripts providing a user interface are forced to use my ActiveX form solution published in my ActiveX sample page (disadvantage: we need to install the ocx-files on all target machines).
Or they can use a simple trick: Just launch a html document in Internet Explorer from a WSH script. If that html document contains a form, this form may be used for user input (a detailed discussion how to implement user forms may be obtained from my article Using Forms in VBScript/JScript). A small script within the html file provides a procedure, callable from the WSH script, to indicate that the user has clicked the OK button to close the form. The WSH script forces IE to load a html form. Then the script polls the form's procedure until a "ready flag" signals that the user wishes to close the form. After receiving this flag, the WSH script reads the user input from the forms input elements, closes the IE session and displays the results. Pretty cool, isn't it.
Unfortunately, security updates of IE and Win XP SP2 blocks active content in html documents. In consequence, after a WSH script forced IE to load a form, the script procedures within the form are not executed until the user allows IE to display active content. The WSH script fails to call a user defined procedure within the form.
Well, this pitfall can be solved using a html form that doesn't contain a script. All actions need to be implemented in WSH scripts. Let's have a look at a simple form.
The HTML code to implement this form will be shown below.
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Form input - by Günter Born</title> </head> <body bgcolor="#C0C0C0" scroll="no"> <h3>Form</h3> <hr> <form name="ValidForm"> <p>Name: <input type="text" size="5" name="Text1"> Age: <input type="text" size="3" name="Number"> <input type="button" name="Button1" value="OK"></p> </form> </body> </html> |
This HTML code is pretty simple - the trick is to assign a name attribut to each form element. This attribut may be used within a WSH script to access the element.
Now it's time to implement a WSH script that forces IE to load the form. Then the script shall wait until the user clicks the OK button. After detecting that mouse click, the script shall read the form's input data, closes the form and displays results. The following code sequence launches IE.
' *** launch Internet Explorer *** Set oIE = WScript.CreateObject("InternetExplorer.Application") oIE.left=50 ' window position oIE.top = 100 ' and other properties oIE.height = 200 oIE.width = 350 oIE.menubar = 0 ' no menu oIE.toolbar = 0 oIE.statusbar = 0 ' commented out, because it causes a corrupted window oIE.resizable = 0 ' disable resizing oIE.navigate path & "Form1.htm" ' Form oIE.visible = 1 ' keep visible ' Important: wait till MSIE is ready Do While (oIE.Busy) WScript.Sleep 100 ' supend, just to lower CPU load Loop
After IE tells us that the form is loaded, the script needs to connect its event handler to the OnClick event of the form's OK button. This may be done using the following two VBScript statements:
' now connect the event handler
Set oBut = oIE.document.getElementById ("Button1")
Set oBut.onclick = GetRef ("GetFormValue")
The event handler, implemented within the script, contains just the code to read the form elements.
' ### Event handler ###
Sub GetFormValue
' User has clicked the OK button, get values
If test Then WScript.Echo "Event raised"
result1 = "Value1: " & oIE.Document.ValidForm.Text1.Value
result2 = "Value2: " & oIE.Document.ValidForm.Number.Value
ready = true ' set ready-flag
End Sub
An element within the form may be accessed using the path to the object like oIE.Document.ValidForm.Text1.Value. "Text1" is the object name assigned within the elements HTML tag using the name attribute. The last statement sets a flag ready to tell the script's main procedure, that the user already clicked the OK button. Then the main script may terminate the IE session using a oIE.Quit statement. Further details may be obtained from the following listing.
'************************************************ ' File: Form1b.vbs (WSH sample in VBScript) ' Author: Günter Born ' ' Uses Internet Explorer 6.0 for form input. Works ' also with Win XP SP2! '************************************************ Option Explicit Const test = false ' set to false to disable Messages Dim oIE ' declare variables Dim path Dim Title Dim Text2 Dim result1, result2 Dim oBut Dim ready Title = "WSH sample form input - by G. Born" Text2 = "You entered:" & vbCRLF ' *** get script path -> because form (HTML file) ' *** must be in the same folder!!! path = WScript.ScriptFullName path = Left(path, InstrRev(path, "\")) If test Then WScript.Echo "Script launched" ' *** launch Internet Explorer *** Set oIE = WScript.CreateObject("InternetExplorer.Application") oIE.left=50 ' window position oIE.top = 100 ' and other properties oIE.height = 200 oIE.width = 350 oIE.menubar = 0 ' no menu oIE.toolbar = 0 oIE.statusbar = 0 ' commented out, because it causes a corrupted window oIE.resizable = 0 ' disable resizing oIE.navigate path & "Form1.htm" ' Form oIE.visible = 1 ' keep visible If test Then WScript.Echo "Wait for IE" ' Important: wait till MSIE is ready Do While (oIE.Busy) WScript.Sleep 100 ' supend, just to lower CPU load Loop If test Then WScript.Echo "Connect handler" ' now connect the event handler Set oBut = oIE.document.getElementById ("Button1") Set oBut.onclick = GetRef ("GetFormValue") If test Then WScript.Echo "Wait, until user clicked OK" 'Wait until the OK button has clicked ready = false Do Until ready WScript.Sleep 100 ' supend, just to lower CPU load Loop ' try to display the results MsgBox Text2 & vbCRLF & result1 & vbCRLF & result2, _ vbOKOnly + vbInformation, Title oIE.Quit ' close Internet Explorer Set oIE = Nothing ' reset object variable ' ### Event handler ### Sub GetFormValue ' User has clicked the OK button, get values If test Then WScript.Echo "Event raised" result1 = "Value1: " & oIE.Document.ValidForm.Text1.Value result2 = "Value2: " & oIE.Document.ValidForm.Number.Value ready = true ' set ready-flag End Sub ' End |
The global variables result1 and result2 are used to pass the results obtained within the event handler to the main procedure. The ready flag tells whether the form may be closed or not. Using this technique, you may access any form's item from your WSH script. And this solution will run also in future IE security updates, because it just contains pure HTML code.
© by G. Born
Disclaimer
Use it at your own risk. Further information about WSH may be found in the WSH Bazaar at: www.borncity.de.
Planned topics for newsletter #11 and future newsletters:
Enyoy scripting, till the next newsletter arrives...
(c) G. Born, 14 - January 2005 (the day the Huygens probe will hit Titan) - www.borncity.de