Microsoft introduced HTML Applications (HTAs) in Internet Explorer (IE) 5.0, so it's been around for a while. For me, at least, it was a nice little jewel tucked away awaiting discovery: HTA came to my attention when I decided to look into what those Microsoft Scripting Guys were using to run their Scriptomatic 2.0 tool.
An HTA is mainly just an HTML page with an .hta extension. However, an HTA isn't subject to the tight restraints or security constraints of an HTML page. Think of HTA as a wrapper for your VBScript scripts. You can use HTML code to create a slick UI to gather user input, and the user can perform actions simply by clicking on specific buttons that run your embedded VBScript subroutines.
My August 2005 article about HTA UIs, "Hooked on HTAs," (InstantDoc ID 46795) laid out the basics of the HTA structure and coding elements and demonstrated a simple input screen that had two input fields and two buttons. This article shows you how to set up more-versatile UIs that you can use to drive your VBScript scripts and utilities. We'll look at the HTA window and the various objects that you can employ to interact with the user. I'll also show you how to associate your VBScript subroutines with buttons.
The HTA Input Box
The VBScripting Using an HTA User Interface input box, which Figure 1 shows, consists of the following elements:
The VBScriptUI.hta file contains the code that creates the input box in Figure 1. You can download VBScriptUI.hta from the Windows Scripting Solutions Web site. Go to http://www.windowsitpro.com/windowsscripting, enter 47533 in the InstantDoc ID text box, then click the 47533.zip hotlink. To view the file, open it in Notepad. In that file, you'll notice HTML code for the following elements:
The textbox. The Change TextBox Color textbox is a regular textbox that accepts any type of input or keystrokes. In this application, its function is to gather a red-green-blue (RGB) combination from the user and change the textbox's interior color. The user is expected to enter an RGB value or a hexadecimal value in the form RGB(r,g,b) or #hhhhhh. Each RGB value can be any number from 0 to 255. The hex value can be any 6-character hex value from 000000 to ffffff. The leading pound sign (#) is optional.
This textbox includes error checking; an appropriate instructional pop-up message displays if the user keys in anything that won't produce a color. The code resets the RGB value to rgb(64,255,64), which overwrites the incorrect user input.
The password box.This box demonstrates the use of a password inputtype textbox. This textbox automatically masks user input with asterisks. The user can key in anything without restriction or error. When a user clicks Display Password, a message pops up that shows the unmasked password that the user entered.
The single-select list box.This simple list has three entries. When users click the drop-down arrow, they can choose Item 1, Item 2, or Item 3. When they click SingleSelect, a pop-up box displays the selected item.
The multiselect list box.This relatively simple list box has three items the user can choose from. But instead of being able to select only one item, the user can select any combination of items. To select multiple items, users need to hold down Ctrl or Shift. The Ctrl key allows non-adjacent selections with a click of the mouse button. The Shift key selects all items between the item selected and the previous selected item (inclusive). When the MultiSelect button is clicked, a message box displays all selected items.
The radio buttons.The user can choose any one of the three radio buttons at any time. When a user clicks RadioButton Selected, a message box displays which radio button is selected. Obviously, in a real-world application, the subroutine associated with this radio button would do more than just display what the user clicked. This example demonstrates that you can determine which radio button was selected and perform a specific action for that button.
The On Change combo box. This drop-down item doesn't use a button to launch the message showing what the user selected. It uses the onchange attribute of the drop-down selection box. For this field, the changing of the selection triggers the associated subroutine.
The check boxes.The user can select one or more of the three check boxes. When a user clicks the CheckBox Selected button, the subroutine associated with the onclick event displays a message for each box that's checked. Here again, you'd do something more than just display what the user selected in a real application.
The Exit button.The Exit button closes the application and the application window by using the short, succinct self.close method. When you use this method, you need to make sure that your subroutines include appropriate cleanup code, such as setting your variables to the Nothing keyword. Alternatively, you might run a cleanup subroutine when the Exit button is clicked instead of immediately closing the application.
Note that the buttons in this application trigger the VBScript subroutines. Each button has an individual onclick event that triggers a specific subroutine to run. In the On Change combo box, a user changing the selection triggers the subroutine. If you used this application as an example when writing your own application, you might have similar buttons, boxes, and text as well as similar subroutines. However, the code in your subroutines would be different.
Inside the Head Element
The code for the VBScripting Using an HTA User Interface input box is too long to print in its entirety, so I'll show only excerpts here. Listing 1 shows the head and style elements in VBScriptUI.hta, which define the input box features and appearance. Between the
The style element defines the look of the internal window of the application. In this case, it's defining the color, font, and margins. The background color in this application is buttonface--a nice shade of gray. The font identifies the name of the font and its point size, and the margins are expressed in pixels.
Inside the Script Element
The script element in VBScriptUI.hta identifies VBScript as the scripting language and contains seven subroutines. The subroutines are where the real work of the application occurs. The HTA input box is mainly a way for you to acquire user input and for the user to select one or more processes to perform. You'll generally have a subroutine for each button in your HTA input box. I won't go into the details of each subroutine here, but a few subroutines warrant some explanation:
The Window_Onload subroutine, which Listing 2 shows, executes when the HTA opens. This is a good place to do upfront work that doesn't require user interaction.
The RadioButtons subroutine, which Listing 3 shows, evaluates whether a radio button is selected. You use the Checked property of the object. You also need to indicate which button you're evaluating. For example, to check the first radio button, you'd use the following code:
If RadioButton(0) _.Checked Then ...
As you can see, radio buttons are structured as an array. Note that the first element number is 0.
The ChBx subroutine, which Listing 4, page 4, shows, also uses the Checked property to determine whether any check box is selected. However, check boxes aren't structured like an array. You evaluate them by their names. For example:
If CheckBox1.Checked Then ... If CheckBox2.Checked Then ... If CheckBox3.Checked Then ...
The SelectMulti subroutine, which Listing 5, page 4, shows, uses the Selected property to evaluate multiselect items as an array. To evaluate whether items are selected, you can use a For...Next statement and code like this:
If (MultiSelect.Options(i) _.Selected) Then ...
Inside the HTA Body
You define the UI buttons, boxes, and drop-down lists inside the body of the HTA. Many attributes are associated with HTML objects, but here I'll list the important attributes that you should be aware of:
In this application, the input type attribute can be "button", "text", "radio", "checkbox", or "password". You can group together radio buttons (input type="radio") as long as they have the same name attribute. However, when you group them, only one button can be enabled at a time. You can group check boxes (input type="checkbox") by their value attribute. After opening the application, the user can select any number of the available check boxes.
The name attribute specifies the name of the object. You can use it in your VBScript code to modify or display the value of the object or field. You refer to a specific item value by its name, followed by a period and the value property. For example, I use the following code to display the contents of the password textbox object when a user clicks the password button:
I clear the password entry box by replacing the value with an empty string with this code:
passwordtextbox.value = ""
You use the value attribute of a Textbox object to set, change, or display the value of that object. The first textbox, for example, initially contains rgb(192,0,0) when the application is opened. A button's value attribute is simply the text on the button face.
The onclick attribute (you could think of it as a method), which I used extensively throughout this demo, refers to an action to perform. With the exception of the Exit button, all onclick actions in this example are linked to subroutines. To associate a subroutine with an onclick attribute, set it equal to the subroutine name. For instance, you'd use onclick="changecolor" for the ChangeColor button to run the routine that changes the background color of the first text input box.
Drop-down lists or selection boxes begin with the select size attribute. Select indicates that you can make a selection, and size indicates how many selections should be visible to the user. You set the attribute to the number of selections you want to display. For example, select size="3" shows the first three selections of the dropdown list. Note that if you want to create a multiselect box in which a user can select more than one item, you must include the multiple attribute. You must also create each drop-down item with the option statement. If you want an item to be selected automatically when the application starts, you need to use the selected attribute as I did in the code <option selected value="Item1"> Item1</option>.
The onchange attribute (think of it as an event), which I used in the On Change drop-down list example, is similar to the onclick attribute in that it performs an action. However, this attribute's action takes place when an item in the selection box changes. When this object changes, it triggers the associated subroutine--in this case, the OnChangeEx subroutine.
The last item of importance is the Exit button. In this demo, it closes the application by using the onclick attribute, but instead of the button calling a subroutine, the action performed is simply self.close.
Change for the Better
HTAs let you create versatile UIs that users will find easy to use. With HTAs, you'll find it much easier to gather a wide variety of user input from within one application and to perform any number of basic or complicated tasks with just a little bit of HTML experience.