Providing Complex Dialog Boxes
Boost your scripts' flexibility
January 12, 2005
JScript, VBScript, and Windows Script Host (WSH) don't provide methods to create complex dialog boxes for tasks such as masked password input, progress feedback, and file selection. You can use Microsoft Internet Explorer (IE) windows to serve as complex dialog boxes, but scripting the creation and presentation of such IE windows typically requires complex coding and a lot of knowledge about IE. To simplify the process, I've written a WSH Windows Script Component (WSC)—Penton.Scripting.IEDialogs—that contains code to create useful IE dialog boxes for instant use from any WSH script. You can also use this component as a starting point for creating custom dialog boxes. (Although the WSC and my discussion focus on VBScript, you can use the component with any scripting language that can use COM objects.) Let's take a look at the creation of an IE dialog box that supports multiline input, examining some of the issues that crop up during the process. Then let's examine Penton.Scripting.IEDialogs and its uses.
Creating an IE Dialog Box
The code in Listing 1 runs through the primary steps of creating a raw IE dialog box that will accept multiple lines of textual input from users. (To simplify the process, we won't worry about presentation details, such as layout.) Web Figure 1, http://www.windowsitpro.com/windowsscripting, InstantDoc ID 44888, shows how this dialog box will appear to users.
The first challenge is IE's asynchronous behavior. IE returns control to the script immediately after a user performs an action such as navigating to a Web page, but IE isn't ready to accept new commands yet, so the script needs to wait until IE is ready before continuing. To deal with this challenge, the code at callout A in Listing 1 uses the WScript.Sleep method, looping until IE's ReadyState goes to READYSTATE_COMPLETE.
The next step is to create and insert any text or HTML elements that you want to appear in the dialog box. For this demonstration, the code creates a multiline text box for entering or pasting data, as well as a button that users will click to submit their input. The code at callout B in Listing 1 shows the pattern for creating such a dialog box. First, the code creates an element from IE's Document object (ie.document.createElement), sets some properties that are specific to this element type, then adds the element as a child of the document body (ie.document.body.AppendChild). Note that this description is fairly generic because many element types exist, each with different attributes. For more information about Dynamic HTML (DHTML) elements, see the Microsoft Developer Network (MSDN) DHTML Objects reference (http://msdn.microsoft.com/workshop/author/dhtml/reference/objects.asp).
At this point, you have an IE window that contains a multiline text box for input and an OK button. The script needs to wait for the user to click the button and for the text to be returned to the script. Because the code initially used text.Value to set the value for the text area (text), we know that the script can simply read in text.Value after the user clicks the OK button (okButton). But how does the script know that the user has clicked the button?
Clicking a button in an IE window triggers a special attribute called an event—the onclick event, in this case. An event is essentially a signal from the button, and you can capture the event by using an event handler. The code at callout C in Listing 1 creates a variable named Finished and sets that variable to False. Next, the code uses VBScript's GetRef function to run a subroutine named OK_Clicked when okButton's onclick event happens. The code at callout E shows that all the OK_Clicked subroutine does is set Finished to True. As long as Finished equals False, the script will loop, as the code at callout D shows. When a user clicks the OK button, the OK_Clicked subroutine will automatically run, setting Finished to True. The script will then display the final text and close IE.
This general approach for using IE from WSH is reliable, but complicated. To simplify the exploitation of several useful dialog boxes, all of which share some common features, I've written the Penton.Scripting.IEDialogs component.
Using Penton.Scripting.IEDialogs
Penton.Scripting.IEDialogs (which you can download at http://www.windowsitpro.com/windowsscripting, InstantDoc ID 44888) is a plaintext file (penton.scripting.iedialogs.wsc) containing a script. To register the component on any Windows computer running WSH 5.6, right-click the file, then choose Register from the context menu. If you use a scripting editor, such as SAPIEN Technologies' PrimalScript, that can read information from type libraries, you can instead select Generate Type Library from the context menu to get component browsing information. You can then call the component from any script running on the system. Listing 2 shows you various ways to use the component.
After you've installed the component, you need to reference it from a script, as the code at callout A in Listing 2 does. The code at callout B sets the created dialog box's width and height (in pixels), sets whether the dialog box displays a scroll bar, and customizes the dialog box's title. (Other than the title setting, the values specified in this code are the internal default settings, so you can omit these settings if you want to keep the defaults.) Also, when you call a dialog box, you must pass it a reference to WScript because the script must sit and loop until an event happens. To do that without hogging the processor, you need to use a WScript.Sleep statement inside the component. Now, let's take a look at the dialog boxes that you can create with Penton.Scripting.IEDialogs.
The Password dialog box. IE provides direct support for dialog boxes that mask display text, so you can use IE to provide a dialog box that masks password entry. First, tweak the height and width settings at callout B in Listing 2 to size the dialog box for a simple text display.
The code at callout C in Listing 2 uses the BeforeText property to display instructional text (in this case, Enter a password). Whatever you set as the BeforeText property will appear above anything else in the dialog box. The code then uses the Password method to call the dialog box, pauses, and waits for the user to enter the password value.
The ConfirmedPassword dialog box. When you want to provide a way to confirm an entered password, you can use the code at callout D in Listing 2. This code uses the ConfirmedPassword method to display two password dialog boxes simultaneously. If the user doesn't enter identical text in both dialog boxes, the component appends an error message to the display and clears the password values. The dialog box won't return the entered text to the script until the passwords match.
The File dialog box. To give users a graphical method for returning a file path to a script, the code at callout E in Listing 2 uses the File method. The code provides a Windows Browse dialog box, then returns the complete path to the file that the user browses to. One benefit to using this dialog box is that it helps avoid the return of nonexistent filenames or paths.
The Selection dialog box. VBScript provides means for users to make simple selections: You can use a MsgBox with simple Yes and No buttons, or you can display an InputBox and require users to type in a matching value or index of some kind. Such methods aren't very user-friendly, though. A drop-down Selection dialog box is a more useful choice because it lets you provide a description for each choice. Users' selections can return data values that the users need never see. The code at callout F in Listing 2 creates a sample Selection dialog box that lets users select a user group. First, the code creates a scripting dictionary object (sd) that contains the friendly name of each option as the keys and the data value that represents each option as the items. Next, the code calls the Selection method with the dictionary object as the second argument. The Selection method returns the value of the selected key. For example, if the user selects Administrators from the dialog box, the value will be 3. The code assigns the returned value to the variable named value.
The Progress dialog box. Creating a progress dialog box that provides a GUI representation of script activity ranks high on my list of annoying WSH scripting problems. No native way exists to accomplish this task by using scripts that run from WScript. You can use WshShell's Popup method to display a dialog box that will go away on its own, but the script pauses during the display of the dialog box. The code at callout G in Listing 2 fills this functionality void by creating a Progress dialog box that doesn't pause your script. The code then returns a reference to the progressDialog object in the component. Each time you call this object's Add method with some string data, the code echoes the string to the dialog box, followed by a space (to ensure that the data will wrap in the window). I added the Sleep loop in callout G just to demonstrate the possibilities. If you're running a script that performs hundreds of operations (e.g., moving files, adding users), you can use the Add method to continually update the output window with data as generic as a period (.) or as specific as a filename or username.
The CalendarDate dialog box. The final dialog box is one that lets users pick a calendar date. IE doesn't provide a general Calendar dialog box, so the easiest solution for me has always been to use the calendar component that comes with Microsoft Office 2000 or later. Therefore, this dialog box will work only on systems running Office 2000 or later. The code at callout H in Listing 2 calls the CalendarDate method to return a VBScript date value. The advantage of this method is that it requires no typing and provides an intuitive interface, so you don't run the risk of users entering different or unexpected date formats.
Get Flexible, Fast
When you need to provide a way for users to return complex information to your JScript, VBScript, and WSH scripts, don't despair. Have fun experimenting with Penton.Scripting.IEDialogs in your test environment, then deliver custom, complex IE dialog boxes to boost your scripting power.
About the Author
You May Also Like