Special effects aren’t limited to the movies
Just as Rollie Tyler and Leo McCarthy introduced special effects, or F/X, to many moviegoers 20 years ago, I hope to introduce F/X to you and many other scriptwriters. Like Rollie and Leo in the epic "F/X" movie, I'll let you in on the secrets behind the special effects you'll see shortly. But seeing is believing. Before you read on, I recommend that you download the HTAspecialEffects.hta from the Windows Scripting Solutions Web site (go to http://www.windowsitpro.com/windowsscripting, enter 49131 in the Instant-Doc ID text box, then click the 49131.zip hotlink). You might be amazed to see that you can make cursors come alive with animation, magically change text without even touching it, make text slowly fade in and fade out, make items quickly disappear and reappear, and more.
If you're unfamiliar with HTML Applications (HTAs) and how to use them as a front end for VBScript files, check out the resources in the "HTA Resources" box, page 16. If you're familiar with HTAs, let's get on with the show.
Let the Show Begin
Let's take a short tour around HTASpecialEffects .hta's UI, which Figure 1 shows. If you hover your cursor over the lower right textbox, you'll see your cursor change to the animated cursor that's currently selected in the adjacent list box. If you hover over the ShowTime button, you'll see the cursor change to a hand pointer. Hovering over the Browse button will demo a raindrop cursor. And hovering over the Exit button will dynamically change the "HTA Special Effects" heading to "Exit HTA Special Effects - Press F1 for Help."
All these special effects are achieved with the onmouseover attribute. Each object's onmouseover attribute has its own event that fires whenever the cursor hovers over that object. The Exit button's onmouseover event calls a subprocedure named ChangeColor, but all the other onmouseover events set the style.cursor property. For example, the ShowTime button's onmouseover attribute is
The hand cursor is built in, or native, to Microsoft Internet Explorer (IE). The Browse button's onmouseover attribute is
The onmouseover attribute of the Hover over this box to see animated cursor textbox differs slightly because it displays the animated cursor that's selected in the list box. D1.value specifies this selection, so the code for this F/X is
As I mentioned earlier, the onmouseover event for the Exit button calls the ChangeColor subprocedure. As Listing 1 shows, this subprocedure changes not only the heading text but also its color. The heading's text and color are reset to their original values as soon as the cursor is no longer over the Exit button—a feat that's achieved with the onmouseout attribute. The event for the onmouseout attribute calls the ReturnColor subprocedure in Listing 1. This subprocedure sets the text and color back to the original values.
Fading In and Out
Now that you know how to animate cursors and magically change text without touching it, let's continue with the tour. Click the Fade Out button. As you can see, three things happen:
- The text directly above the button slowly fades out and some new text appears.
- The button's label changes from Fade Out to Fade Back.
- While the text is fading, the cursor changes to whatever you have selected in the animated-cursor list box.
When you click the Fade Back button, the new text and new label fade away and the previous text and label fade back in. This fade F/X is achieved with the SPAN element, which Listing 2 shows. The SPAN element lets you encompass a portion of text within another element for special processing. You can assign an ID to the SPAN element and reference the ID in order to apply unique style filters (which affect the way in which content is displayed) and transitions (which affect the way in which content changes are displayed). For example, the Span1 ID is used in the FadeIt function to apply special effects. (I'll elaborate on the FadeIt function shortly.)
You use the onfilterchange attribute to detect the end of a transition. When a transition ends (in this case, when the text finishes fading in or out), the onfilterchange event triggers and the cursor is reset to the default arrow.
The other noteworthy attribute within the SPAN element is the position attribute. In this example, the position attribute is set to relative. This setting enables the text to stay in the same position relative to the rest of the window, should the window be resized.
When you click the Fade Out or Fade Back button, the onclick attribute event calls the FadeIt function and passes the Span1 ID to that function as a parameter. As Listing 3 shows, the FadeIt function receives this ID in the variable named obj. With the needed information in hand, the function first sets the cursor style from within a subprocedure named ChangeCursor. ChangeCursor sets the cursor to whatever is selected in the animated-cursor list box.
Next, the FadeIt function checks the value of the button's label to see whether it's Fade Out. If it is, the function changes the button's label to Fade Back and performs a fade transition. If the label is Fade Back, the function performs a fade-in transition and changes the button's label to Fade Out.
Callout A in Listing 3 highlights the code that changes the label and performs the fade-out transition when you click the Fade Out button. Recall that Span1 is passed to the FadeIt function in the obj variable. So, anything applied to the obj variable actually gets applied to the Span1 object, which ultimately is the text that fades in and out.
To use a filter, you must begin by setting the style.filter property to a specific predefined filter. In this case, the blendTrans filter is used. This filter accepts a duration parameter, which specifies how long the transition should occur. In this example, it's set to 7 seconds. After the filter is selected, you use the Apply method to prepare the SPAN element for content changes. However, the changes don't actually take place until the Play method executes.
The next line of code sets the style.visibility property to hidden, which means the Span1 object (which contains the existing text at this point) will fade out when the blendTrans .Play method executes in the following line. While in the hidden state, the text changes to the string specified by the innerText property.
To make the new text fade in, you apply the same techniques. After the filter is selected and prepared, you set the style.visibility property, but this time you set it to visible rather than hidden. When the Play method executes, the Span1 object (which contains the new text at this point) fades in. This transition also takes 7 seconds. The cursor is reset at the end of this transition because the onfilterchange event fires. Callout A in Listing 2 shows the code that resets the cursor by executing the resetcursor subprocedure.
The Disappearing Act
Text isn't the only thing you can make vanish into thin air. You can make buttons, boxes, and other items disappear and reappear at will. For example, in the UI in Figure 1, click the HideBrowse button. Notice that the Browse box and ShowFileSelected button in the upper left corner of the UI vanish and the HideBrowse button becomes the ShowBrowse button. To make the Browse box and ShowFile-Selected button reappear, simply click the ShowBrowse button. Similarly, you can make a clock and a WhatTimeIsIt button appear and disappear by clicking a button whose label toggles between ShowTime and HideTime.
The DIV element makes such disappearing acts possible. The DIV and SPAN elements are similar to each other in that whatever attribute is applied to that DIV or SPAN is applied to everything within its start and end tags. More important, you can use IDs in DIV elements the same way you can use IDs in SPAN elements. Unlike the SPAN element, the DIV element can include line breaks. (The SPAN element at callout A in Listing 2 appears to have line breaks, but it doesn't in the actual HTA code. Column widths in the printed publication force us to wrap code.)
As Listing 4 shows, there are two DIV elements in this sample HTA and both are defined with absolute positions (i.e., 50 pixels from the top and 10 pixels to the left). So, both occupy the same space. However, the first DIV element (which contains the time objects) has its style.visibility property set to hidden, so only the browse objects in the second DIV element appear when the application starts up. Thus, you can use one area of your UI to display different elements.
Setting the Stage
Before you can use special effects in HTAs, you need to set the stage so that they work properly. In previous HTA articles, I demonstrated the use of the Window_Onload event, which takes place when an HTA is launched. In HTASpecialEffects.hta, I use another Onload event that differs slightly from the Window_Onload event. The new Onload event resides in the BODY element and executes before the Window_Onload event. The Onload event occurs while the browser is loading, whereas the Window_Onload event occurs after the browser has finished loading the page.
The Onload event calls the Startup subprocedure into action. This subprocedure sets up the HTA window size and initializes the timer used to display the time of day. It also uses Windows Management Instrumentation (WMI) to gather the names of the .ani files that reside in the C:\ WINDOWS\Cursors or C:\Winnt\Cursors folder. These files contain the animated cursors. Windows XP has quite a few animated cursor files, but unfortunately Windows 2000 has only one that I have seen in my tests. The Startup subprocedure populates the animated-cursor list box with the collection of .ani filenames.
Immediately after the Startup subprocedure runs, an Onhelp event calls the ShowHelp subprocedure. As its name implies, this subprocedure provides Help information. The Onhelp event is triggered whenever you press the F1 key.
The Window_Onload event uses the Focus method to initially activate the animated-cursor list box. Typically, I use the Focus method to place the cursor immediately into a user input textbox. In HTASpecialEffects .hta, however, I set the focus on this list box so that users can simply press the DOWN ARROW key on the keyboard to quickly scroll through the animated cursors to see which cursor they want to use. Note that for the animated cursors, fade transitions, and the other special effects to display properly, the system's color palette must be set to 256 colors or better.
Spruce Up Your HTAs with F/X
HTASpecialEffects.hta only begins to scratch the surface of the special effects you can achieve with HTML filters and transitions. I hope it helps you get an idea of how you might enhance your VBScript HTAs.
Windows Scripting Solutions
"Handy HTAs: Set and Display User Quotas," September 2005, InstantDoc ID 47101
"Use an HTA as a UI for Your VBScript Scripts," October 2005, InstantDoc ID 47533
"Add a Little Color to Your World," November 2005, InstantDoc ID 47800
"Introduction to Filters and Transitions," http://msdn.microsoft.com/library/default.asp?url=/workshop/entry.asp
HTA Helpomatic, http://www.microsoft.com/downloads/details.aspx?FamilyId=231D8143-F21B-4707-B583-AE7B9152E6D9&displaylang=en