For the most part, the Script Component Wizard succeeds in automating the process of creating a script component so that you can focus on the code needed to implement your component's logic, rather than on the code needed to implement basic "plumbing" so that the component can work properly. In a number of areas, however, WSC offers functionality that either requires some additional coding or that extend the functionality of VBScript in significant ways. These include handling events, using interface handlers, taking advantage of resources, and building object models.
9.4.1 Handling Events
VBScript itself provides no native support for firing or handling custom events. Its support for events is limited to the Initialize and Terminate events, which are fired when a new instance of a class defined by the Class...End Class construct is created or destroyed, respectively. (And, in fact, they're not real events: the scripting runtime simply calls the routines if they're present.) Support for any other events must be provided by the environment in which VBScript is running.
In the case of Windows Script Components, WSC requires that an event be declared using the element. Its syntax is:
where name defines the name of the event, and dispid is an optional attribute that assigns the event's dispatch ID. Ordinarily, WSC automatically provides a dispatch ID to identify an event. You might want to provide your own dispatch ID to map a custom event to a standard COM event, or to insure that dispatch IDs remain the same across different versions of your component.
Once the event is defined, you can fire it from your code. For this, you use the WSC fireEvent method. Its syntax is:
where eventName is a string containing the name of the event to be fired. Multiple events can be fired by separating them from one another with a comma. The use of the fireEvent method is illustrated by the boldface line of code in Example 9-3.
Once the event is fired, it must also be handled by the client application using the event definition facilities provided by the client environment. Example 9-3, shown earlier in Section 9.3.2, illustrates how an event is handled in a WSH script. In the code, the ConnectObject method of the WScript object is invoked to indicate that the script should receive event notifications for the math object.
9.4.2 Using an Interface Handler: ASP
The element in a .wsc file allows you to define the interface handlers that are available to your script. The element's syntax is:
The element has the following attributes:
The name of the interface handler. In scrobj.dll WSC provides an ASP handler for Active Server Pages and a Behavior handler for DHTML. A third handler for COM automation is automatically referenced without an element if the element is encountered in a .wsc file.
An optional element that defines the name by which the interface handler will be referenced in code. Since referenced interfaces are in the script's global namespace (that is, they do not have to be referenced through an interface object), id is typically used only to uniquely identify an object or member when there is a naming conflict between multiple interfaces.
An optional Boolean that determines whether the value of the internalName attribute is assumed in scripts, so that the referenced interface resides in the script's global namespace and does not have to be referenced through an object. By default, its value is true.
Ordinarily, once the interface handler is defined, interface classes and members can be referenced as if they were native to the component. In the case of ASP, for instance, an implements element like:
means that the ASP intrinsics are globally accessible to a WSC component. As a result, the number of items in the Contents collection of the Application object, for instance, can be retrieved with the following line of code, which is identical to the code that would be used within an Active Server Page itself:
Dim iCount = Application.Contents.Count iCount = Application.Contents.Count
Example 9-4 shows a simple ASP component that displays information from the intrinsic ASP Request object. Although most of the code is straightforward, several features are worth noting:
but is instead accessed in Example 9-4 as:
Example 9-4. A simple component for ASP
Example 9-5 provides the HTML source for a page that requests the ASP page whose listing appears in Example 9-6.
Example 9-5. An HTML page
Using an ASP Component
Enter your name:
Example 9-6. An ASP page that uses a Windows Script Component
<% Dim info Set info = CreateObject("ASPInfo.WSC") Response.Write "Your Browser: " & Info.Browser & " " Response.Write "Server Name: " & info.ServerName & " " Response.Write "Your IP Address: " & info.RemoteAddress & " " Response.Write "Your Name: " & Server.HTMLEncode(info.Value("name")) & " " %>
9.4.3 Using Resources
Typically, strings are handled by hardcoding their values throughout one or more scripts. This creates a maintenance nightmare when the strings need to be modified or localized. To deal with this problem, WSC offers the element, which allows a value to be associated with a resource identifier. The syntax of the resource element is:
resourceID must be a string that uniquely identifies the resource in the component; it is, in other words, a key value. value is the string or number that is associated with the resource identifier.
Example 9-7 illustrates one possible way to use resources. The component has a SayHello method that returns a string in one of four languages. The language name serves as the key or resource ID that provides access to the localized string. The user can then select his native language from a drop-down list box (see the HTML page in Example 9-8). An ASP page (see Example 9-9) instantiates the component, retrieves the user's name and language choice from the Request object's Form collection, and uses the language as the key to look up the localized version of the greeting.
Example 9-7. A component that uses resources
Good day Dobar dan Bonjour Guten tag
Example 9-8. HTML page allowing the user to select a language
Using a ResourceEnter your name:
Your native language: EnglishFrenchCroatGerman
Example 9-9. ASP page that uses the Greeting component
<% Dim greet, lang, name Set greet = CreateObject("Greeting.WSC") lang = Request.Form.Item("language") name = Request.Form.Item("name") If Not name = "" Then Response.Write greet.SayHello(lang) & ", " & name Else Response.Write "You have failed to provide us with your name." End If %>
9.4.4 Building an Object Model
Often when you work with your component, you don't want to instantiate just one object. Instead, you want to instantiate a parent object, which in turn builds a hierarchy of child objects.
To build an object model in this way with Windows Script Component, you can include multiple components in your .wsc file. This requires some modification to the basic .wsc file created by the Script Component Wizard:
You can then instantiate all but the parent or top-level component by calling the Windows Script Component's createComponent method. Its syntax is:
Set object = createComponent(componentID)
where object is the variable that will contain the object reference, and componentID is the name assigned to the component by the id attribute of the element.
Example 9-10 illustrates the use of the createComponent method to instantiate child components. A parent Workgroup object contains a Users component, which in turn contains zero or more User components. When the workgrp component is instantiated, a users object is also automatically instantiated; it is accessible only through the workgrp object's Users property. When the users object's Add method is called, a user object is added to the array held by the users object.
Example 9-10. A three-component object model