DAY 11

More ActiveX Controls


CONTENTS


Yesterday you had the opportunity to get acquainted with perhaps the most simple of the ActiveX controls, the label control. You know what an ActiveX control is all about. Now it's time to expand your ActiveX control repertoire. The purpose of this lesson is to move you from the realm of a one-control developer to a jack-of-all-trades control expert. The best way to reach the point where you have the confidence and background knowledge to use any control is to see a variety of controls at work. This lesson will achieve that by introducing two more very important controls: the new item control and the timer control.

By learning about these controls, you will gain exposure to a wider variety of control properties and events representative of a broader range of controls. You will also see further examples of applying controls to specific solutions through the sample programs. Additional controls will be introduced after today throughout the rest of the book, but in the context of specific solution areas. By the time you have digested the nuts and bolts of today's controls, you will have enough general control background to easily apply similar control integration techniques to other controls you will later encounter.

The New Item Control

The new item control is one of the new generation of ActiveX controls that seems to have been introduced specifically to solve a common Web page problem. Often on Web pages, new material is highlighted with a graphic or a new indicator to let the user know that a certain piece of content was recently added. For example, if a computer book store lists its stock of books on a Web page, it might have a brightly colored "new" graphic after any book titles that were added to the list in the last week or so. Users visiting the page are more likely to take a look at the title if their attention is drawn to the fact that the item is a recent addition.

Suppose you have a page that documents the behavior of VBScript, and you add an addi-tional hypertext link to some important notes. If you have a lot of information grouped on the page, even your frequent visitors might overlook a specific piece of new material unless you call their attention to the fact that it is a new piece of information. Similarly, consider the case of an ice cream shop advertising its flavors. Highlighting any new flavors from a lengthy list would not only ensure that users are aware of the new introductions-but it would probably also help those flavors to sell.

All these cases demonstrate a need to draw the users' attention to the new items. The typical way to do that is through a splashy new graphic that makes a piece of material stand out on the page as new content. Figure 11.1 shows the page for an ice cream store that uses such a graphic to point out a new flavor. When you view the page with this graphic, you have a clear impression in your mind afterward of what the new flavor is.

Figure 11.1 : A page that uses the new item control to highlight new information.

The use of such graphics is not hard to implement, even without controls. You simply add the graphic to your page. It does present some maintenance nightmares, however. You have to make sure that you change the page with the new item as soon as the item is no longer new. If you have a lot of pages, all with new items, you have a lot of maintenance to perform. You have a lot to track and a fair amount of pressure. What if things are busy and you don't have time to perform this low-priority maintenance, or what if your webmaster goes on vacation for a couple weeks? Then you are left with "stale" new items. Nothing turns users off faster than to see something flagged as new day after day. It leaves the same impression as the appliance store that has a big "going out of business sale of the century" sign in its window week after week. Eventually, you begin to tune out the sign and question the credibility of the sign poster.

Maintaining new item indicators is often a low-priority, tedious but important, high-visibility task. As with most such tasks, it is a natural choice for a more automated solution. The new item control provides such a solution. You can position it anywhere on a page just as you would an image, but most often you position it after new material on a page. When you add the new item's object declaration to a page, you associate an image file with it. The control will then display this image, which is typically a "new" graphic, on the page.

The real power of this control is that you can also associate a date with it. The image will only be displayed until the given date. After that, it will no longer show up on the page at all. You can have 100 new items on 100 different pages. Perhaps all of them should be deactivated on a given week, but the webmaster is off on a sabbatical to Katmandu when that week comes. Everyone else who could fill in is in the middle of meeting a busy deadline. Nobody has time to go back and remove the new indicator graphics from the pages. If you've used the new item control, it doesn't matter! The new item indicators stop appearing automatically on the designated date. As a matter of fact, you never have to remove the new item indicators from those pages if you don't want to. The new item controls have, in effect, activated a conditional display for you. They will never again display the graphic as long as the date of that condition is past.

Object Definition

The first step in using this feature in your page is to add the appropriate object declaration for it. The ice cream page new item shown in Figure 11.1 was actually generated by a new item control. Listing 11.1 shows the declaration for that control.


Listing 11.1. New item control declaration for a new flavor on the ice cream page.
<OBJECT
id=newCone4
classid="clsid:642B65C0-7374-11CF-A3A9-00A0C9034920"
width=0
height=0
align=middle
>
<PARAM NAME="date" value="5/22/1999">
<param name="image" value="yum.bmp">
</OBJECT><BR>

Attributes

Some pieces of this definition probably look quite familiar from yesterday. Each object control declaration supports the same attributes. That is one of the advantages of a well-defined object standard; once you've learned to handle one object, the same knowledge applies to integrating other objects as well. The ID attribute is the familiar identification label. The name you assign here will be what you use within your code if you reference this control. classid indicates the name or number that this class of control has within your system registry. This tells the browser its family of controls and therefore provides the path to its implementation. With ActiveX controls, the browser can determine the type from the classid information, so that information is not specified here.

The width and height attributes tell the browser how much space to make for the graphic on the page. Because the attributes are 0 here, the browser decides how much space to use based on the size of the graphic. As a matter of fact, as long as these attributes are less than the size of the graphic, and even if they are omitted from the attribute list altogether, the browser will use however much space it needs for the graphic. If the attributes specify an area larger than the size of the graphic, however, that much extra space is used on your page and will show up as a blank area. The align attribute is also the same one discussed yesterday and simply aligns the image with the middle of the preceding text area.

Properties

Now that I've addressed the object attributes, it is time to turn your attention to the properties of the control that are defined through the parameter tag. The properties are typically more relevant to the programmer because it is these elements that you can adjust from your program. The new item control has two such properties: image and date.

The image property provides the image to be displayed. This is defined in terms of a URL address of a location on the World Wide Web or a local filename for the file that contains the image. This image can have any of the standard graphics formats a normal image has. Although this image typically displays a "new" indicator graphic, this is not a requirement. The image can be anything you assign it-a bright logo that says "new," a graphic of a setting sun, or even a picture of your dog playing Frisbee. Regardless of the content, it is simply an image that will be displayed until the desired date is reached. If you don't specify any image or you designate an image file that is not present, the new item control will render its own default image for you. That image is a standard "new" indicator, as shown in Figure 11.2. You cannot access the image property within your script with the present new item control. You can only specify it within your object declaration, and then you cannot change or read it within your script program.

Figure 11.2 : A page that uses the new item control with the default "new" image.

The date property specifies the "expiration" date; once this date is reached, the control ensures that the image is no longer displayed. This date must be specified in standard date format such as 10/1/96. Your script program can both read and write to this property.

Methods and Events

Many controls have methods and events that you can use. Other controls do not. The new item control falls into the second category. The control does its work without providing any major methods for you to call or generating events that you can respond to. The new item control does support one minor undocumented method, the AboutBox method. If you have a statement in your program that triggers the AboutBox, such as newControl.AboutBox, an About box displays and shows information about the control. This is typically used to provide control integration information but is not something you are likely to rely on heavily in your programs. An example of a typical About box is shown later today when I describe the next control.

Setting Properties for the New Item Control

Now you know a little about what the new item control can do. As a matter of fact, you might be thinking, "Where's the programming?" You bought a programming book, but here you are, reading about a control that doesn't seem to have much to do with programming. You plop it in your page, and it's ready to go. It might seem that there isn't much opportunity to write scripts that use this control. You saw just a couple properties, only one of which you can change. You can specify all the standard property values to control the display through an object declaration. Without any real methods or events for your program to interact with, this is basically a pretty simple control that you can integrate just with an object declaration.

Nevertheless, you can still interact with this control within your programs in a very dynamic fashion, as you will soon see. This is precisely why I highlight this control here-to illustrate that even though a control might not give you a lot to work with in terms of properties, methods, or events, you can still accomplish a great deal with it from VBScript. A newcomer to VBScript might read the new item control definition and determine that it's not really a programmable control. With a little thought and creativity, however, it can be.

Before looking at a sample solution that uses the new item control, first consider how its properties are modified. I provide a new item control property tweaker program for this purpose. Remember from yesterday that the term tweak is often used to mean experiment or slightly change. That is exactly what the new item tweaker control lets you do-experiment with the date property, the one and only property of this control that you can change. Figure 11.3 shows the new item property tweaker Web page. I'll explain the new item tweaker program by examining a series of key code blocks. You might want to skim over the structure of the entire Web page and its embedded script first to help you understand the overall context of the various code examples you will see.

Figure 11.3 : The new item property tweaker program.

Note
You can find the new item tweaker program on the CD-ROM with the name newtweak.htm.

The new item tweaker uses two new item controls-one after each of the two large lines of text that appear at the top of the page. Notice that each new item control displays a different image, which illustrates that you can use any image with a new item control on the same page. Typically, you will use the same new indicator for every new item for consistency, but this is not required by the control.

At the bottom of the page is a property box that enables you to respecify the date property for each of these controls. When you click the Assign Properties button, the values you supply are immediately applied to the control. When you first load the program, the dates you see are those that have been assigned to the new item controls through their object declarations. These dates are retrieved and assigned to the date text boxes with code that reads the date property as the page is loaded. Listing 11.2 shows this code.


Listing 11.2. Reading the new item date property to display the initial date setting.
<SCRIPT LANGUAGE="VBSCRIPT">
<!--

     '  ------------------------------------------------------
     '  STARTUP Code: these statements are carried out on page load.
     '  Retrieve initial values from the new item controls
     '   to display them in the textbox at startup
         txtLine1.value = newSample1.date
         txtLine2.value = newSample2.date
     '  ------------------------------------------------------

... more subroutines here

-->
</SCRIPT>

The date is accessed by simply referencing the date property of the new item controls and assigning that to the text box. In the sample code, the two new item controls are named newSample1 and newSample2, and the text boxes are named txtLine1 and txtLine2.

The object declarations for the new item controls precede the script in the HTML file and have the format shown in Listing 11.3.


Listing 11.3. Object declaration for new item control in the new item tweaker program.
<OBJECT
id=newSample1

classid="clsid:642B65C0-7374-11CF-A3A9-00A0C9034920"
width=200
height=100
hspace=10
vspace=5
align=middle
>
<PARAM NAME="date" value="12/28/1996">
<param name="image" value="cool.bmp">
</OBJECT>

You can see from the object declaration that the designated date for the newSample1 new item control is December 28, 1996. Until that time, the graphic cool.bmp will be displayed. Once that date is reached, the graphic will no longer be displayed. The starting page shown in Figure 11.3 demonstrates that this is working correctly. The cool.bmp graphic does indeed appear because the suppression date had not yet been reached at the time the program was run. The date retrieved from the newSample1 data property and displayed in the property box at the bottom of the page corresponds to the initial object date. The other new item control graphic also appears because the suppression date for that object is set to July 6, 1998.

Now it's time to experiment with changing the date. Assume that you provide new dates of April 10, 1996 and March 6, 1996 in the new property input text boxes. Then, click the Assign Property button to execute the new assignments. The new assignments are made to the new item control by assigning the new values to the date property of each control. Listing 11.4 shows the code.


Listing 11.4. Code to assign new date properties.
sub cmdAssign_OnClick
    ' update the New Item control properties when button clicked
         newSample1.date = txtLine1.value
         newSample2.date = txtLine2.value
    end sub

The code is again quite straightforward. Text box control values are assigned to new item control date properties. As soon as this script completes, the controls immediately update and display the result on the current Web page. Figure 11.4 shows that result.

Figure 11.4 : The new item property tweaker program with dates changed to be prior to today.

As you can see, the graphics no longer appear. The control detects that the date to start suppressing the graphics has already been reached based on its current date property and therefore does not display the associated image.

The new item tweaker program demonstrates that a new item control does dynamically react to dates modified through VBScript. Next, you can use it to gain some insights into valid date formats. Another test that you can perform with the new item tweaker program is assigning a date in the year 2000. For example, specify 5/4/00 as a new property value. You might expect that the new item image would be displayed after you click Assign Properties because the suppression date is some time off. Surprise! The image does not appear as expected but is suppressed immediately. This demonstrates that the new item control, at least in its beta incarnation, does not support dates for the year 2000 and beyond. This is behavior you can likely expect future versions of the control to fix.

Now, try a test relating to the internal storage format of the control. Use the property modification area at the bottom of the page again to specify a date of April 10 1996. Notice that this date is in a different format from those specified before. Next, click the Apply Properties button. The date assignment takes place…or does it? What do you think is stored in the new item control's date property now?

There is a way to find out. If you click the label at the very top of the screen, which has the caption "Shows only if prior to date," the script executes code that displays the current date setting of the new item control in a message box. If you take this action to inspect the current date, you get the result shown in Figure 11.5.

Figure 11.5 : Feedback from the new item property tweaker program when you enter a legal date of April 10 1996.

As you can see, the date supplied as April 10 1996 was treated as a legal date. It was converted and stored internally in the control as 4/10/96. Now, see what happens if you assign a date that is more clearly illegal, say cat3/6/96. Enter that into the lower property text box and click Assign Property. Once again, click the label at the top of the page to inspect the current value stored in the control. Will you see a valid date there? Figure 11.6 shows the result of the inspection.

Figure 11.6 : Feedback from the new item property tweaker program when you enter an invalid date of cat3/6/96.

The result shows that a new date was not assigned, but the old date remains.

It is helpful to understand what happens after you assign a property to a control, as you have seen from the previous examples. It is easy to make an inspection with a few lines of code that evaluate the property when the label is clicked. Listing 11.5 shows the code executed for this evaluation when you click the label.


Listing 11.5. Code to inspect a variable.
sub lblInfo_Click
' display date info when label clicked
     Msgbox AnalyzeDate(newSample1.date),0,"newSample1 Date Analysis"
     Msgbox AnalyzeDate(newSample2.date),0,"newSample2 Date Analysis"
end sub

function AnalyzeDate(CurDate)
'--- This subroutine is called to analyze the date format
     dim svDate, svTemp

     ' See if format is legal
     if isDate(CurDate) then
         svDate = "Date: " & CurDate
     else
         ' Illegal format, store detailed analysis
         svDate = "Date not in legal format."
         svDate = svDate & "  Vartype is "  & vartype(CurDate)
         svDate = svDate & ".  Length= " & len(CurDate)
         if len(CurDate) > 20 then
              svDate = svDate & ".  Too long to display."
         else
              svDate = svDate & ".  Contents: " & CurDate
         end if
     end if

     ' Return value
     AnalyzeDate = svDate

end function

This code calls a function, AnalyzeDate, that analyzes each control. That function makes a check to see if the new item control date property is a valid date. If it's not, the code performs more checks to see what type of data representation is stored in the control and to view its size if it's a string.

This analysis code shows that the new item control, at the time of this writing, stored everything correctly. Only valid dates could be stored. In very early alpha versions of this control, a large string of meaningless data would be stored when an invalid date format was provided to the control. This is no longer a problem, but the process of investigating it is pointed out to emphasize the kind of groundwork you often must do when integrating controls into your applications. You have to check them out and understand them first! If you want to inspect the behavior of later versions of this control or any other control to figure out how it is behaving and write your code accordingly, you have an easy means at your disposal. You can simply use the new item tweaker or a program like it to fully understand the behavior of the control. You will find over time that your own experimentation scripts are probably as informative to you in shaping your control approach as any manuals you might find or advice you might receive from others.

Looking at the new item control has highlighted another important point: Always keep in mind that it is very important to have a full understanding of any control you integrate. Oftentimes, the easiest and most comprehensive way to gain that understanding is to use test scripts such as the new item tweaker.

Dynamically Adjusting Program Feedback with the New Item Control

You've now had the rundown on the capabilities of the new item control and seen how to explore those capabilities with a test program. Now it's time to take a look at a more real-life application. Refer to today's first figure, Figure 11.1. This figure shows a page for a fictitious ice cream store that offers a variety of flavors of ice cream for sale. Its market niche is the wacky flavors it creates. Successful business for this ice cream store depends heavily on marketing these flavors. As a result, it is very important for this business to drum up interest in any new flavors it creates.

This is the purpose of the new item control you see in Figure 11.1. The webmaster for the ice cream store (who gets paid in consumables) has to ensure that every new flavor added to the page has a new item control after it so that the new flavor is initially highlighted. However, the ice cream store doesn't want to highlight the flavors too long. If it did, it would risk having its page visitors start to believe none of the information was that current and end up ignoring any new indicator. It sets the expiration date of the new item controls to expire after one week from the time of introduction. After that point, the new item image is automatically suppressed, and the flavors are no longer highlighted.

This bothers the webmaster, though. He knows that a lot of page visitors only stop in every few months. When they visit, one of their prime areas of concern is what flavors have been introduced since their last visit. The webmaster knows he could build a fancy CGI script with a database on the server to let visitors request update lists, but he doesn't even have access to a server. The ice cream parlor's pages are hosted on a gigantic mega-provider service that doesn't let its customers write any server-side control.

Fortunately, it occurs to the webmaster that he doesn't need a server! With some clever scripting, he can easily build a date-oriented search approach right around the very same new item control that is already being used. The approach consists of using the new item controls as an index of when the flavor was introduced. Then, if the user supplies the date when he last visited the page, the code can examine the new item date properties and determine which flavors should be flagged as new flavors for the user. For the flavors that should be highlighted, the script can simply reassign the image suppression date to be some point in the future. Then, the graphic will be displayed.

What does it take to make this happen? First of all, you must have a standard input text box at the bottom of the page. In addition, you need a button the user can click to indicate he wants a date search to take place. Then, you need some code to examine each flavor-associated new item control whenever the user specifies that the search should occur. Listing 11.6 shows that code.


Listing 11.6. Code that displays new item controls for all the flavors that have been added after the user's last visit.
<SCRIPT LANGUAGE="VBSCRIPT">
<!--

    dim datOrigCone1, datOrigCone2, datOrigCone3, datOrigCone4

    '---  Startup code carried out when page loads --
    ' Store the original dates of New Item controls for each flavor.
    '   These are used to restore to original settings later.
    datOrigCone1 = newCone1.date
    datOrigCone2 = newCone2.date
    datOrigCone3 = newCone3.date
    datOrigCone4 = newCone4.date
    '------------------------------------------------

    sub cmd96_Onclick
    ' Highlight all new items if they are for a flavor that was
    '   introduced after the user's last visit. We can determine when
    '   a flavor was introduced by looking at the date of the New Items.


    Dim datLastVisit, datFlavorIntro

     ' Make sure a date has been provided
     if len(txtLastVisit.Value) = 0 then
     msgbox "Please enter date of last visit!",0,"Missing Date"
        exit sub
     end if

     ' Use the date specified to see if flavors have changed since
     datLastVisit = txtLastVisit.Value

     ' Check to see if we should force item 1 to display by shifting date
     datFlavorIntro = newCone1.date
     if cdate(datLastVisit) < cdate(datOrigCone1) then
         ' They haven't seen this flavor, so extend the corresponding
         '   new items display range to encompass today
         newCone1.date = "12/31/99"
     else
         ' This flavor isn't new to user, use original flavor date
         newCone1.date = datOrigCone1
     end if

     ' Check to see if we should force item 2 to display by shifting date
     datFlavorIntro = newCone2.date
     if cdate(datLastVisit) < cdate(datOrigCone2) then
         ' They haven't seen this flavor, so extend the corresponding
         '   new items display range to encompass today
         newCone2.date = "12/31/99"
     else
         ' This flavor isn't new to user, use original flavor date
         newCone2.date = datOrigCone2
     end if

'... Similar checks take place for all other new items

Note
The Web page containing this script is available on the CD-ROM that comes with this book in the file newscoop.htm.

Notice that in Figure 11.1 only one flavor was highlighted as new. Suppose you go down to the last visit prompt, specify that you haven't visited the page since April 7, 1996, and then click the highlight button. Now you will see two flavors highlighted-all the flavors that are new for you. You can see this result in Figure 11.7.

Figure 11.7 : The Scoops page when the user enters a last visit date of 4/7/96.

Assume your ice cream-swilling buddy comes over and notices you have the page up. She remembers she last visited the site around the spring of 1995, and she's very curious about what they have added since. You specify her last visit date and reselect the highlight button. Now, four flavors are highlighted on the page, as shown in Figure 11.8.

Figure 11.8 : The Scoops page when the user enters a last visit date of 5/22/95.

The ice cream Web page can do a lot for the user. Of course, it shows all the flavors available, which is easily accomplished through standard HTML. It also indicates which flavors are new as of today, which happens through the new item control simply by virtue of the object . No code is required yet. Then, it also lets the users perform a historical search and highlights all new flavors introduced after the date they specify. It does this without requiring any interaction with a server. All the search capabilities take place locally through VBScript and a creative use of the new item control property. This example shows that you can't always judge the power of a control by the size of a property and event list. The new item control doesn't give you much to work with, but when coupled with the power of VBScript, it can still present to the user a seemingly smart Web page.

Timer Control

So far, you've seen controls that are visually oriented. The label control and the new item control both communicate visual information to the user. Our scripts can control to some extent this visual communication through the control properties. Ultimately, the power of those controls is in the picture they paint on the page. Now to round out your picture of the range of capabilities of ActiveX controls, it's time to consider a different type of control. This is the type of control that is not visually oriented. It never appears on the screen.

Pages are certainly a visual medium. What good is a control that you can never see? The power lies in the fact that your scripts can make use of a nonvisual control. Code can use a nonvisual control to help make decisions, display other elements, perform calculations, and so on. The specific control in this nonvisual category that I tackle next is the timer control. As its name implies, this control is used for timing purposes. However, the concept of interacting with a control the user can't see through your code will apply to many other controls as well. For now, I focus specifically on what the timer control can do for you.

You can assign the timer control some specified period of time and turn it on from code or from its initial object declaration. Once turned on, the timer starts a timed countdown, but the countdown is out of sight and out of mind as far as your script and Web page interaction are concerned. The timer is out there dutifully counting down, but you don't see any signs of it-that is, until the entire time period has elapsed and the countdown reaches zero. When that happens, a timer-related event occurs. If you have associated code with this event, the code is executed at that point. Once your code completes, the timer starts the countdown over again, if you didn't write code to explicitly turn it off.

You can picture the timer control as somewhat like a kitchen timer. Assume you ask your child to set the timer for 10 minutes and to call you when the timer buzzes. (Your child is playing the role of the timer control.) You settle down on the couch for a quick chance to study the patterns on the ceiling. Just as you're dozing off-er, rather, mastering the layout of the patterns-you are rudely shaken. A shout in your ear informs you that the timer went off. (The timer event has occurred.) At this point, you lean forward on the couch, look around to make sure the house isn't on fire, and then slump back down. (You have just performed actions in response to the timer event.) Your child has been through this many times before and knows just what to do. She troops back into the kitchen and sets the timer for another 10 minutes. The scene will be repeated over and over until one of two circumstances prevails. Either you finally get up and leave (and the program is terminated), or one time when the child wakes you at the regular 10-minute interval, you inform her that she doesn't need to set the timer again because you intend to be studying the ceiling patterns for some time to come. (You've just turned off the timer control.)

An analogy can only take you so far, and so it is with the timer control. An important consideration to keep in mind is that the user of the Web page never sees a timer control. It has no visual representation. It does have a code representation: an object declaration, an event procedure you can define, properties you can set, and methods you can invoke.

The timer control is not intended to be something the user sees; it is a building block for your scripts. There isn't only one reason to use a timer. You might have many different reasons to build a timer control into your script. Any action that should occur after a precisely specified interval is fair game for implementing with a timer and the code you can associate with a timer expiration. Perhaps you want a program to make a label on your Web page periodically change color and catch the user's attention. Maybe you want to refresh a Web page at regular intervals with a new advertising slogan. Maybe you're a Lamaze instructor and you want to write a program that guides couples through timed relaxation and breathing exercises. The possibilities are endless. All you need is a timer control, its object declaration, and some basic knowledge about its properties and main timer event.

Object Declaration

The object declaration for the timer control looks somewhat similar to the other types of controls covered so far. You can see a timer control object declaration in Listing 11.7.


Listing 11.7. The object declaration for a timer control.
<!------------- Timer object definition  ---------->
<OBJECT
classid="clsid:59ccB4A0-727D-11CF-AC36-00AA00A47DD2"
CODEBASE="http://www.microsoft.com/workshop/activeX/gallery/ms/timer/other/
          ietimer.ocx#version=4,70,0,1112"
id=timer1
>
<param name="Interval" value="5000">
<param name="enabled" value="0">
</OBJECT>

This declaration has only a couple differences from other object declarations. As with all controls, classid indicates the type of control it is and provides the browser's path to the implementation behind the control. The classid in the preceding code is therefore specific to the timer class of control. The ID serves the same purpose as in the other examples; it lets you define the name that you will use when you refer to the timer in your code. The timer does not have many of the attributes you've seen in other object declarations that relate to appearance. Because you won't see the timer on-screen, you don't have to specify those attributes. Some of the appearance attributes do have an effect if you choose to use them, oddly enough. The declaration in Listing 11.8 creates a large blank space on your page, reserved for the timer. The best approach for attributes is to use them only if you need them and go with a minimal declaration like that in Listing 11.7. The CODEBASE attribute was also used here to point to a master source for this control. This would allow the browser to automatically retrieve it if it was needed and not currently on the system. You can use CODEBASE with any control definitions. Base the decision on whether you want your pages to automatically trigger such downloads for your page user.


Listing 11.8. A timer declaration with width and height attributes, which makes blank space on the page.
<!------------- Timer object definition ---------->
<OBJECT
classid="clsid:59ccB4A0-727D-11CF-AC36-00AA00A47DD2"

id=timer1
width=1000
height=1000
>
<param name="Interval" value="5000">
<param name="enabled" value="0">
</OBJECT>

Properties

The more interesting part of the timer control declaration is the properties declared through the parameter statements in Listing 11.7. The two main properties for the timer control are enabled and interval. enabled determines whether the timer is turned off or on. If enabled is set to -1, which represents a true value in VBScript, the timer is in an enabled state. In other words, the timer is turned on and it's counting down the given time period. When the specified time period has gone by, the timer event procedure will be called if one exists. If enabled is set to 0, on the other hand, the timer is turned off. In this disabled state, no timer countdown occurs, and the timer event procedure will not be called.

The interval property specifies how much time must elapse between turning on the timer and calling the associated event procedure, if any. The interval property is so named because it defines the interval between timer events. This value must be specified in terms of milliseconds. A second has 1000 milliseconds, so to set the timer for 5 seconds, you would set the interval property to 5000.

The greatest amount of time that you can set for the timer interval property is about 64K seconds, or 65534 milliseconds. If you need to time a duration that lasts longer than 65 seconds, you have to write code that uses the shorter timer expiration event repeatedly to gauge when some longer period of time has elapsed. If the interval value is set to 0 or less, it essentially disables the timer. No timer events will occur. Note that the interval property does not change as the timer counts down. The timer keeps track of its countdown progress internally, and the interval property itself always indicates the last interval that was requested.

Event

The timer event occurs whenever the timer is turned on and the specified timeout interval has expired. If you have defined a timer event procedure in your code, that event procedure is called when the timeout interval expires. The approach for defining control-related events was discussed in detail on Day 10, "An Introduction to Objects and ActiveX Controls." The key to remember is that you must couple the name of the control, as specified by the ID attribute, with the control's predefined event name. With the timer control, the predefined event name for an interval expiration is simply Timer. To define a timer event for a control named Timer1 then, you would supply a subroutine such as that shown in Listing 11.9.


Listing 11.9. A subroutine to handle the time event for a timer control named Timer1.
<SCRIPT LANGUAGE="VBSCRIPT">
<!--

    '---  Startup code carried out when page loads --
    ' Display the initial settings of the timer control
    txtEnabled.Value = timer1.enabled
    txtInterval.Value = timer1.interval
    '------------------------------------------------

    sub timer1_timer
    '--- Timer event carried out whenever the timer goes off

       ' Show the message box if user requested it
       if txtMessageBox.value = 1 then
            MsgBox "The timer has expired!",0,"Message"
            txtMessageBox.value = 0
       end if

       ' Shift label up or down each time
       if lblEvent.angle = 0 then
            ' Move it up
            lblEvent.angle = lblEvent.angle + 5
            lblEvent2.angle = lblEvent2.angle - 5
       else
            lblEvent.angle = 0
            lblEvent2.angle = 0
       end if

       ' Move the old current event info to the prior info area
       lblEvent2.caption = lblEvent.caption

       ' Show the current time in the timer
       lblEvent.caption = "Timer went off at " & now

       ' Update the total number of events
       lblTotalEvents.caption = lblTotalEvents.caption + 1

    end sub

The timer's time event is the code in subroutine Timer1_Time. It is important to be clear on one point in particular when you use timer events. When a timer event occurs, your event code gets executed. If you do not turn off the timer by changing its Enabled property, it will immediately start another countdown, using the same TimeOut interval that was previously specified. In this manner, the timer will keep running and triggering the event procedure indefinitely until the browser is no longer loaded with that page or until some area of code sets the Enabled property to 0.

You are not required to have a timer event procedure. Of course, it does you little good to use a timer if you do not have an event procedure to go with it. You can't perform useful work with a timer unless you have a means to know when the timer has expired. The only way to tell is to supply code in the event procedure.

You can have more than one timer. Each timer typically has its own event procedure. The Enabled and Interval properties can be different on each timer. Multiple timers on one page are usually completely independent. Assume you want to have one label that changes colors every second and another label that switches its angle every fifth of a second. You could implement this with one timer by having the timer interval occur every 200 milliseconds and writing code that handles both cases. Of course, label color should only change once every second, so you'd have to include code to make sure that happens only on every fifth event. However, it is often easier to use two separate controls in such a case. One control can trigger an event every 200 milliseconds to move the first label, and the other control can trigger an event every second to update the color of the second label. This makes for much cleaner code.

You should keep in mind some special code considerations with a timer that are not as relevant to other controls. Once you load a page with a timer and enable it, what happens if you switch to another page, or for that matter, another program? Suppose a timer event occurs every second, and each time it occurs, a counter variable is incremented. If you switch to a previous page in the browser or a different program such as a word processor, the timer event will continue to be triggered under Windows 95. When you come back to your timer page after leaving it for 12 seconds, the timer would have been incremented 12 times. This behavior might vary based on the operating system and environment because it has to do both with an operating system's multitasking capabilities and the browser and VBScript run-time implementation.

Methods

The timer control has only one method-the AboutBox method. You call this method from your code by referencing the control name, a period, and the method within a code statement:

Timer1.AboutBox

When this statement is executed, a box with information about the timer control is displayed. This is probably not an activity that the user of your Web page will need on a frequent basis. However, the need to support such a method is significant in the World Wide Web model because users will start to use more and more controls that come along for the ride with the Web pages they pull up. People will begin to pay more attention to where a control comes from and what it is. The AboutBox method lets you determine this information and provides an easy way for you to give the user access to this information. An example of the AboutBox for the timer control will appear in the sample program that follows.

Setting Properties for the Timer Control

The first step to using the timer control is having a firm understanding of its properties. I provide a handy timer tweaker program for this purpose. It will enable you to execute a series of property modifications on the timer so that you can observe the effects. In addition, this script will log all timer events that occur by displaying them right on the page. This makes it easy for you to see how properties and the time event relate. Figure 11.9 shows a picture of the timer tweaker page. At this point, the page has just loaded, and no timer events have occurred yet.

Figure 11.9 : The timer tweaker program before any events have occurred.

As you can see from Figure 11.9, the timer is not turned on in its initial state, and the interval of time to use once it is activated is 5 seconds. Both of these settings were determined by the attribute values provided in the timer object declaration. This declaration was shown previously in Listing 11.7. The initial values that are displayed when the page loads are retrieved from the timer's Enabled and interval properties. You can see the code that extracts these properties and displays them on-screen in the first several lines of Listing 11.9.

Note
The timer tweaker program described here is available in the file timetwk.htm on the CD-ROM.

You can start the timer tweaker timer by changing the Enabled Property text box to -1 and clicking Apply Properties. If you watch the event log area of the page, you will see that the label begins to update with news of events. Every 5 seconds, the event occurs and the label is updated. Old event information is shifted to the secondary label. In addition, the labels' angles are shifted so that the user has a clear visual sign that timer event activity is occurring.

Refer to Listing 11.9 to see the code that performs these updates. The code associated with the procedure timer1_timer will be executed every time 5 seconds goes by. Because the timer1_timer subroutine has no code that turns off the timer, it immediately restarts the countdown and keeps repeating this periodic event trigger. Figure 11.10 shows the program after nine events have occurred. If you carefully examine the information that is displayed in the event information labels in this figure, you can see that the timed events are occurring every 5 seconds as expected.

Figure 11.10 : The timer tweaker program after nine events have occurred.

To stop the timer from triggering the timer event procedure, you can simply supply a 0 to the Enabled text box. When you click the Apply Properties command button, the Enabled property of the timer is updated accordingly, and the countdown will come to a halt. Listing 11.10 shows the code that is executed after you click the Apply Properties command button.


Listing 11.10. A subroutine that assigns the properties of the timer.
sub cmdApply_OnClick
   Timer1.Enabled = txtEnabled.value
   Timer1.Interval = txtInterval.value
end sub

Now assume that the timer tweaker program is modified by the user again. He sets Enabled to -1 and interval to an interval of 2000. Then, he clicks the Apply Properties button. At this point, the timer will trigger the event procedure at 2-second intervals. Figure 11.11 shows the display on the page after this interaction. The label readouts show that the period between events now is 2 seconds.

Figure 11.11 : The timer tweaker program with the interval set to 2 seconds.

Note
It is possible under some operating system circumstances to have timer events occur at some period slightly off the interval you specified. The timer interval is quite reliable on a multitasking system such as Windows 95 but can be affected by severe performance demands if a significant amount of other activity is occurring on the system. Likewise, the precision can vary between operating systems. Generally speaking, the timer is reliable for non-timing-critical purposes. If you were writing what's known as a real-time program where guaranteed response at the millisecond level is critical, such as a program that controls a low-level device, then the timing reliability might be less than ideal. You probably wouldn't be writing such software using VBScript because it's not a language targeted for that kind of work.

The timer tweaker program has another option available. You can specify that you want to see a message box when the next event occurs. If you set this option on, the timer's time event generates a message box. Listing 11.9 shows the code for this action under the comment Show the message box . You can see an example of the message box that is generated in Figure 11.12. The most interesting use of this in testing the timer event is demonstrating how the timer continues even after you move to other Web pages. Turn on the message box generation through the page, and then move back to another page. Note that the message boxes continue to be generated even when the timer tweaker page is not the current page. The timer still counts down, and the event procedure is still triggered when appropriate.

Figure 11.12 : The timer tweaker program with the message box generated on each event.

You can also use the timer tweaker program to observe what happens when you assign an invalid value to the interval property. First, set the interval property to 5000 milliseconds if it's not already there. Then use the property assignment area to try to assign an invalid property value of "goofy" to the interval property and click the button to perform the assignment. Inspect the current property value after this bad assignment is attempted by clicking the Timer About button. That button displays, in addition to the About box, a message box that shows the timer's current property state. You can see the code in Listing 11.11.


Listing 11.11. Code to show the current timer property state, as well as the About box.
sub cmdAbout_OnClick
         msgbox "Current Enabled property is " & Timer1.Enabled & _
            " and Interval property is " & Timer1.Interval, 0, _
            "Property Inspection"

         ' Display the timer's About info
         Timer1.AboutBox
    end sub

You will see that the interval value is still 5000 milliseconds. The timer control is smart enough to ignore bad data and still retain its prior valid setting. I mentioned earlier that the maximum value the interval property can take is 65534 milliseconds. Try to set it to 70000 milliseconds and inspect the value again. You will see it once again remains at 5000 milliseconds. If you try to assign a value that is larger than the maximum, the timer control doesn't set itself to the legal maximum. Instead, it remains set at the original value. Finally, set the value to 65534 milliseconds. Inspect the value to see if it was retained. You will see, as shown in Figure 11.13, that you have succeeded in setting the timer for 65 seconds.

Figure 11.13 : The timer tweaker program showing maximum interval setting of 65534.

The code that is executed when you click the Timer About button has one other aspect that bears consideration-the use of the AboutBox method itself. The last line of code in Listing 11.11 calls the AboutBox method for the timer control. This simply causes the control itself to display a message box with information about its name and version number. You can see this About box in Figure 11.14. The version number information can come in handy if you run into problems, both for you and the user who uses your Web page. Where it is practical, it is a good idea to make this information available; perhaps you can associate it with a label click for a label discretely placed at the bottom of the page that reads "Version information for controls used with this page."

Figure 11.14 : The timer tweaker program About option.

Providing Dynamic Feedback in Your Web Page with the Timer Control

Now that you've mastered the timer properties, it's time to see an example of how you can provide to your user interactive programs based on the timer. The Heart Timer program shown in Figure 11.15 provides this type of feedback.

Figure 11.15 : The Heart Timer program after dynamic timer feedback.

The Web page directs the user to measure his pulse for 60 seconds and provides a timer to make this as easy as possible. The program lets the user initiate the start of a timer. Listing 11.12 shows the code that starts the timer.


Listing 11.12. Starting the timer at the user's direction.
sub cmdStart_OnClick
        ' Set the label to the starting state to count the seconds
        lblFeedback.fontsize = 20
        lblFeedback.forecolor = &HFF
        lblFeedback.caption = 0
        ' Start the timer
        Timer1.Enabled = 1
    end sub

Once the timer starts, it's very important to provide dynamic feedback to the user. Not too many users will be content to stare at a Web page for some timed period if they have no visual feedback that the timing is underway. The timer's time event provides an easy way to give that feedback. The program needs to measure a period of 60 seconds, but a goal is also to provide progress feedback to the user every second during that 60 seconds. The original timeout interval of the timer was set to 1000 milliseconds rather than 60000 milliseconds in the object declaration.

At the end of each second, the timer time event is called, and a counter is incremented to keep track of how many seconds have elapsed. Each time the event is called, the current number of seconds is displayed at the bottom of the page in the feedback area in a large colored font. The user sees a steadily advancing counter every second as he continues to take his pulse. He knows exactly how much time remains. When 60 seconds are up, the program informs the user that his pulse measurement is complete and turns off the timer. Listing 11.13 shows the code that accomplishes this.


Listing 11.13. The time event that displays continuously updating user feedback.
sub timer1_timer
    '--- Timer event carried out whenever the timer goes off
       ' Keep track of how many seconds have gone by
       lblFeedback.caption = lblFeedback.caption + 1

       ' if 60 seconds have elapsed the user should have a pulse
       '   count, so stop timer
       if lblFeedback.caption = 60 then
           Timer1.Enabled = 0
           msgbox "60 seconds have gone by. Please enter the total "&_
           " number of heartbeats counted!",0,_
           "Time up for counting 60 second resting pulse!"
       end if

    end sub

Once the timing is complete, the user can enter the number of pulses he counted and click the Analyze button to see what that means. Note that the output from the Analyze button appears in the same label as the second-by-second feedback. Usually, the timer will be complete before the final feedback appears there. If not, the timer data would wipe out the final feedback data because the timer data is written every second. As a result, you must take one more safeguard in this kind of program. Because the user might get impatient and click Analyze even as the timer count is progressing, the code for the Analyze button immediately turns off the timer as a precaution. This ensures that the final feedback, if requested before the 60 seconds is completed, will not be overwritten. Listing 11.14 shows the code that accomplishes this.


Listing 11.14. Disabling the timer before presenting final feedback.
sub cmdPulse_OnClick

       ' Ensure that timer is turned off
       Timer1.Enabled = 0

       ' Set label font back to normal size and color for feedback
       lblFeedback.fontsize = 20
       lblFeedback.forecolor = &H00


       ' Provide feedback based on heartrate
       if IsNumeric(txtPulse.Value) = 0 then
           lblFeedback.Caption = "You have no heart!"
       elseif txtPulse.Value < 40 then
           lblFeedback.Caption =  _
              "Very slow heartbeat. You need to get out more!"
       elseif txtPulse.Value < 60 then
           lblFeedback.Caption =  "Good heartbeat - Healthy as a horse!"
       elseif txtPulse.Value < 90 then
           lblFeedback.Caption =  "Average heartbeat, nothing to fret about"
       elseif txtPulse.Value < 110 then
           lblFeedback.Caption =  "Somewhat on the high side...been exercising?"
       elseif txtpulse.Value < 140 then
           lblFeedback.Caption =  "Quite high, may want to seek medical advice"
       elseif txtpulse.Value < 180 then
           lblFeedback.Caption =  _
              "Very high resting pulse...better get it down!"
       else ' Over 179
           lblFeedback.Caption = "Tremendously high...just been bungee jumping?"
       end if

    end sub

As you can see, with a little attention to detail, you can easily build code around the timer control to give your Web pages a high degree of timed interaction and feedback.

Other ActiveX Controls

There are many ActiveX controls available today. Vendors across the world have custom ActiveX controls on the market that you can purchase. Microsoft shares its standard ActiveX controls for free. So far this book has considered only some of the Microsoft ActiveX controls. Availability of types of controls may increase in the future. Even today there are plenty of free Microsoft controls to choose from in building your solutions. One of the ones that hasn't been discussed yet is the Microsoft gradient control. This control lets you blend a range of colors for striking visual effects. Another Microsoft control is the stock ticker control. This can display a continuous ticker tape-type summary of data from a file or other URL resource in the expected format. If the data resource is continually refreshed, the stock ticker tape control will display a constantly updating stream of data. Even if the data file does not change, the stock ticker tape will display a continuous scrolling of the same data. The image control is one that is very likely to be a part of most VBScript Web page solutions. It offers the image presentation capabilities of the <IMAGE> tag and more. With it you can hide an image control, for example. There are many more controls, properties, and methods than can be documented here.

Keep in mind that you can integrate any control with VBScript. The first step in getting familiar with a control should be to refer to its documentation. Review all the properties, methods, and events for a control. For the Microsoft standard controls, this information is on the Microsoft Web site at www.microsoft.com/intdev under the active control topic. When you encounter a new control that you are considering integrating with your VBScript code, pay particular attention to the events it supports. These can help highlight the ways you can use the control as part of your Web page solution. A sample page, MoreCtl.htm, is included on the CD-ROM to illustrate some of the additional Microsoft ActiveX controls. It's a good place to start looking when you're thinking about expanding your control repertoire.

Summary

Today's lesson builds on the information in Day 10 to provide more details on how to effectively deploy ActiveX controls in your VBScript Web pages. The focus is on two specific controls, but the intent is largely to show the overall control integration approach you can use with VBScript. The two controls used to illustrate this approach are the new item control and the timer control.

The new item control displays a preset graphic image on the screen until the specified suppression date is reached. When that day arrives, the graphic no longer appears on the page. Today you have learned about the advantages of learning about a control and integrating it through a property experimentation program. You have produced a rather sophisticated dynamic inventory feedback program around the very simple new item control. This illustrates that even a simple control can be put to very powerful uses if it's applied creatively.

The timer control is a control that has no visual representation on-screen. Like other similar controls, it is provided as a construct that you can build scripts around, rather than as a visual component the Web page user will see. The timer event makes it possible to execute a block of code at specified intervals. Through code, you can control the length of the intervals and whether it responds repeatedly or only once. An example shows how the timer control can provide dynamic feedback to users during timed events.

Today's lesson is important for two reasons. The specific controls it covers are very useful. You might find yourself incorporating them into a lot of your Web page scripts now that you are well versed in their capabilities. Additionally, you now have a very well-grounded exposure to controls in general. You know what it means to use a control; you can declare it, experiment with it to understand its capabilities, and integrate it into your code. The heart of VBScript is really its capability to merge powerful components into a page. You now have unlocked the door to this capability and can proceed through the days to come with this key firmly in hand.

Q&A

Q Are you limited to one new item control or timer control on a page?
A No, as today's examples demonstrate, you can have multiple instances of these controls. Just declare each with its own object declaration.
Q Is there a click event for the timer control?
A No, there is only a timer event for the timer control, which is called when the timer is turned on and the set interval expires.
Q Do I have to use a standard graphic with the new item control to indicate new Web page content? Can I change this through code?
A No. You should keep an eye to the approach commonly used on the Web, which is the new indicator in blazed yellow. However, you can use any indicator you choose. The new item control lets you provide your own graphic. In some cases, it enhances your Web pages to use a more customized graphic, such as in the ice cream store example with its ice-cream-cone-based new logo. You cannot change the graphic through code as your script runs. You must set it ahead of time in the object declaration.

Workshop

Today you saw a Web page that provided timer-based feedback while a user took his pulse. Can you think of other Web pages that might benefit by incorporating a timer as part of the page? You could present a series of test preparation pages that provide sample questions with recommended times for completion and then provide the answers. Try to implement a few pages with such an approach. Note that you can implement the time limit, provide the time limit notification, and even check the answer on a page and give feedback by using local client code. No server code is required.

Quiz

Note
Refer to Appendix C, "Answers to Quiz Questions," for the answers to these questions.

  1. Write an event procedure for a timer named MyTimer. Assume that this timer has an initial timeout interval of 2 seconds. Make this procedure shorten the timer interval to 1 second the first time it is called, one-half second the second time it is called, and finally turn off the timer the third time it is called. You could use several possible solutions for this.
  2. Assume you have a new item control named MyItem, and it is currently displaying the new item graphic. You want to force this graphic to not be displayed in your code. Show the one code statement you can use to do this. There are many right answers, but the concept is the same in all of them.