HTML pages should be interesting as well as functional. The average Web user is familiar with a computer environment in which functionality is provided by visually pleas- ing controls, such as a toolbar or a menu list. While the HTML controls add basic visual support, such as the button, they lack the range of visual functionality familiar to the user. ActiveX controls are a great way to make Web pages interesting while still providing a great deal of additional functionality. A Web page that contains a few common ActiveX controls gives users the visual benefits of a regular computer application along with the capability to interact with the Web page.
At the time of this writing, the only Web browser that fully supports ActiveX controls is the Microsoft Internet Explorer 3.01 (or higher). The HTML standard that de- scribes the inclusion of ActiveX controls can be found at http://www.w3.org/pub/WWW/TR/WD-object.html. The HTML tag that supports ActiveX controls is the <OBJECT> tag. I will assume that you are currently using Internet Explorer as your main browser from this point on.
The Object tag's original purpose was to replace the current tags of IMG, EMBED, and APPLET. These tags all load specific objects. The object tag makes the HTML code nonspecific but includes an attribute to specify which type of object it is. But the Object tag does more than just support ActiveX controls.
The Object tag allows the browser to determine if it can support the object type (MIME type) before it downloads the object from the server. If the browser doesn't support the mime type, the HTML code between <OBJECT> and </OBJECT> can point to an alternative object type to download. For example, there are many sound file types. Some provide for richer sound quality but also require special applications to play their types of sound.
In this example, the Object tag can specify the special application but can still provide a different, lower-quality sound file as an alternate type. The alternative should be a generic type that is widely supported on the Internet. If no suitable alternative object exists, HTML text can be added to tell the user that something is not being loaded and can perhaps point to a download location for the appropriate application, such as the advanced sound file. Microsoft Internet Explorer has limited support for non-ActiveX actions of the Object tag; the example of the advanced sound files' use of the Object tag is not fully supported in the Microsoft 3.0 browser.
http://www.blooberry.com/html/intro.htm This is a great resource for information on which browser supports which tag and which attributes.
Listing 36.1 illustrates the general use of an Object tag. (Don't worry about the syntax, which will be explained later.) The object type and mime type in the listing are meant to be placeholders only. They have no corresponding object. Therefore, the text and image should be displayed instead of the fake object. This listing shows you how to compensate for the browser's inability to load the object. Every Object tag should have an alternate display, such as a link or text, so that browsers that don't support objects can still go through your site. Do not expect this page to work in your browser; the following code is meant to be an example.
TIP: You will be using the code in Listing 36.1 as a template to create the next couple of projects in this book. You can also use this for your own development efforts by placing any additional code after the <BODY> tag.
<HTML> <HEAD> <TITLE>Object with Alternative Text</TITLE> </HEAD> <BODY> <OBJECT DATA = mydata.abc TYPE = "Application/myapp"> <A HREF="http://www.download.com">Download </A> the necessary application from here. </OBJECT> </BODY> </HTML>
The Object tag has a beginning and an ending tag. The attributes placed in the opening tag give object information, such as the object's name and where to download it. The object can have parameters, so the <PARAM> tag is provided to support passing parameters to the object when it is loaded. For an ActiveX object, these parameters are the ActiveX control's properties. The browser displays any HTML text or tags that are between the Object tags if it cannot load the object. If the Object cannot be loaded, then the Param tags are ignored. Any supported HTML tags can be placed in between the Object tags.
CAUTION: You can't guarantee that you will always have access to the <PARAM> tag to set properties in an ActiveX control unless it was created using Visual Basic 5.0.If the control is created with Visual C++ or another high-level language, the capability to set properties through the <PARAM> tag must be programmed by the developer via the PropertyBag, or the developer must use the Data tag. The Data tag is described in the following section.
The Object tag's attributes let the browser know how to display the object. Before the object is fully displayed, the ActiveX layer in Microsoft Internet Explorer attempts to load the control based on those attributes. Table 36.1 lists all of the attributes that apply to ActiveX controls. (There are more attributes in the specification, but they are not related to ActiveX controls.) One good place for getting the complete ActiveX specification is at http://www.microsoft. com/activex/. Another possibility is the ActiveX SDK, although the SDK is currently under-going revisions on a continual basis.
Attribute Name | Function |
Align | Position of the object |
Border | Border of the object |
Classid | Class identifier of the object |
Codebase | URL location of the object |
Data | Encoded initialization information (See the caution in the following section, "Attributes that Load the ActiveX Control.") |
Declare | Object is declared but not loaded until it is referenced |
Height | Height of the object |
Hspace | Horizontal gutter of the object |
Id | Reference name of the object |
Name | Name of object when passed in a Form tag |
Type | Mime type |
Vspace | Vertical gutter of the object |
Width | Width of the object |
Some of the Object tag attributes are used to load the control correctly, while others are used to reference the object (such as in a VBScript). Still others are used to visually display the control. The first set of attributes focuses on the loading attributes, the second set focuses on referencing the attribute with code, and the third set of attributes focuses on the display of the control.
While some of the attributes are not critical to the object loading, a couple of attributes have to be set in order correctly for the object to be loaded. The main attributes of an ActiveX object are the CLASSID (this should be familiar to you by now) and the CODEBASE. The classid, the unique identifier for this control, allows the browser to find the control. The codebase is where you download the control. As with all attributes, the correct syntax is Attribute="value" when the attribute name is not case-sensitive. The following examples show how the CODEBASE attribute could be used.
CODEBASE="http://www.mydomain.com/myindex.html"
or
codebase="http://www.mydomain.com/myindex.html"
In the preceding examples CODEBASE will be treated the same as codebase because the attribute portion is case-insensitive.
The CLASSID Attribute The CLASSID attribute value should include the classid of the object, prefaced with the characters classid:. The classid value can be found in The Registry at HKEY_CLASSES_ROOT\XYZ\CLSID; XYZ is the name of the control. Figure 36.1 shows a picture of The Registry on a Windows 95 machine for the control names MSGrid.Grid. Notice that the classid on the right side of the figure is a huge number. This is the number you want to place in the classid attribute. The following example shows how the classid for the MSGrid control would be placed in the CLASSID attribute.
classid="classid:A8C3B720-0B5A-101B-B22E-0AA0037B2FC".
FIG. 36.1
The Registry on Windows 95 and NT 4.0 holds the classid for each control registered
on your system.
TIP: The Registry in Windows NT 4.0 can be accessed via the REGEDIT.EXE application (just as in Windows 95). This application is used to navigate through The Registry just as the Windows file system can be navigated with the Explorer.
When you get to the point where the regedit application looks like Figure 36.1, you can double-click the entry on the right side. This action brings up a dialog box. You can select that text (the classid) and copy it (Ctrl+C)). You can then paste the number into your HTML page. Do not alter the number in any way. If you do, your browser cannot find the control.The preceding example, ComCtl2.Animation.1, contains the version number. By looking at this name, you can see that the version number is 1.
Listing 36.2 illustrates how a Web page can use just the classid attribute. The Web page is entirely correct only if the control does not need any initialization data (such as properties), is not referenced via VBScript, and is already on the machine. Few controls meet that criteria. Do not expect this page to load a control in your browser; this code is meant to be an example.
<HTML> <HEAD> <TITLE>Basic ActiveX Control Page</TITLE> </HEAD> <BODY> My interesting Web page. <!-- added Classid reference [daggerdbl] <OBJECT CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0"> </OBJECT> </BODY> </HTML>
The CODEBASE Attribute The CODEBASE attribute should be the URL location where you download the control. The URL should look like any Web address: http://www.mysite.org/controls/mycontrol.ocx, for example. As long as the control's extension is .OCX, you don't need to supply any more information. OCX should be the default extension if the control is built with Visual Basic 5. If you know that the control is already on the client's machine (such as a company intranet of only Windows machines), you don't need to use the CODEBASE attribute. Before the browser downloads the control, it checks to see if the control currently exists on the system. If the control does exist, the browser checks to see if the control is the correct version (if one is specified). The browser is finished with the CODEBASE attribute if the control is the correct version. If the version is not correct (but the control is on the machine), the browser downloads the control and registers it. If the control does not exist on the client machine, the browser downloads the control and registers it.
The control's version is denoted in the CODEBASE attribute by adding a #Version= and then the version number. The version number's syntax is a four-part number, each part of which is comma-delimited. If you right-click an executable file (EXE) in your Windows operating system, the version property page will have the version number, such as 4.00.31.85. The periods are replaced with commas for the HTML page. The program automatically adds the version to the control when the programmer builds it. The programmer must ensure that different "versions" of the same control have different version numbers. The higher the version number, the more recent it is. 4.00.31.85 is a newer version than 4.00.31.70.
Developers can easily choose any extension for the control they want. If the extension is not OCX, then the download has to be a *.cab (short for cabinet) file. The cab file is a compression technique that makes the control smaller as it is shipped across the Internet. One file that can go in the cab file is the information file (*.inf), which tells the browser what to do with the control and any files that are in the cab file. Because this book assumes that controls are built with Visual Basic 5, you can assume that controls used in this book have the extension of OCX. Visual Basic 5's Books Online has a section about cab files.
http://www.microsoft.com/workshop/prog/cab/ There is a complete Cabinet Developer's SDK at the Microsoft site. The SDK can be used to create Cabinet and Diamond files for your ActiveX controls and Java applets.
CAUTION: Building a cab file can be a simple task or a complex task, depending on what you want to happen to the files in the cab file. For example, if the control has an extension of .XYZ and isn't dependent on any other files, the only action the browser needs to perform is to register the control. The browser automatically registers the control if the extension is OCX. However, if the control is dependent on several other files (such as initialization files or other dynamic link libraries), the browser needs to be told where to put those files and any information that must be added to the system Registry.
Listing 36.3 defines a Web page that uses the classid and the codebase. The codebase can be an absolute reference to a Web page (the first object on the page), or it can be a relative reference from the location of the calling Web page (the second object on the page). Do not expect this page to load a control in your browser. This code is meant to be an example only.
<HTML> <HEAD> <TITLE>Basic ActiveX Control Page</TITLE> </HEAD> <BODY> My interesting Web page. <OBJECT CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" <!-- Added codebase to point to mycontrol.ocx [daggerdbl] CODEBASE="www.mysite.com/scripts/mycontrol.ocx"> </OBJECT> <OBJECT CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" <!-- added codebase reference [daggerdbl] CODEBASE="/../../scripts/mycontrol.ocx"> </OBJECT> </BODY> </HTML>
You use the DATA attribute to initialize the ActiveX control properties through 64-bit encoding. You cannot read the properties' values after they have been initialized because the initialization is encoded. The encoding is meant for small, but complex initialization. If an ActiveX control is poorly developed in a high-level language, 64-bit encoding is used for the initialization of all of the properties. There are two drawbacks to using the data attribute. You have to know how to generate the 64-bit encoding, and debugging is difficult because the coding is so hard to read. (If you don't have to use the DATA attribute, use a much easier equivalent, PARAM tags, discussed in "Working with the <PARAM> Tag" later in this chapter.)
Listing 36.4 illustrates a sample Web page that uses the data attribute. Notice that the value of the attribute is prepended with information about the encoding and the MIME type. The control in this listing is the Calendar Control 40.0.
<HTML> <HEAD> <TITLE>Basic ActiveX Control Page</TITLE> </HEAD> <BODY> My interesting Web page. <OBJECT ID="Calendar1" WIDTH=288 HEIGHT=192 CLASSID="CLSID:8E27C92B-1264-101C-8A2F-040224009C02" DATA="DATA:application/x-oleobject;BASE64,K8knjmQSHBCKLwQCJ ACcAgAACADEHQAA2BMAAM0HBAAXAA8AAIAAAAAAAACg ABAAAIAAAKAAAQABAAIAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAC8AkRCAQAFQXJp YWwBAAAAkAFEQgEABUFyaWFsAQAAALwCwNQBAAVBcmlhbA=="> </OBJECT> </BODY> </HTML>
TIP: If you have a hard time deciphering the encoding of the preceding listing, two Microsoft programs are designed to make this type of work easy. Microsoft's ActiveX Control Pad (free on the Microsoft Web site) is an elementary application that adds ActiveX controls to a Web page. Because it is free, the functionality is bare and the support from Microsoft is nonexistent.
Microsoft's Visual InterDev (part of the Developer Suite) has an advanced version of the ActiveX Control Pad. Once you select the object you want to add to the page, a property sheet appears (just as it does in Visual Basic). You fill in the property sheet and design the visual properties of the object. When you insert the control into the page, the properties are set for you, either through the Data attribute or the Param tag (discussed in "Working with the <PARAM> Tag" later in this chapter).
The DATA and TYPE Attributes If you use the DATA attribute and the data is just an URL (instead of encoding), you need to use the TYPE attribute to let the browser know what type of data is being retrieved. If the browser doesn't support that MIME type, the data is not downloaded and the object is not initialized. Remember that using the data attribute as an URL is the hard way to work with the popular controls on your Windows 95 or Windows NT machine (depending on the control, doing so may be impossible). The popular controls generally need for the properties to be set through the data attribute that is encoded or set through the PARAM tag (discussed in "Working with the <PARAM> Tag" later in this chapter). If you have created your own control, using the DATA attribute as an URL and using the TYPE attribute to specify the MIME type may work for you. Listing 36.5 illustrates how to use the DATA and TYPE attributes together. Do not expect this page to load a control in your browser; this code is meant to be an example. If you compare Listings 36.5 and 36.4, you can see that when the data is encoded, the data type is already included. When the data is not encoded, the MIME type has to be specified via the TYPE attribute.
<HTML> <HEAD> <TITLE>Declare Attribute</TITLE> </HEAD> <BODY> <OBJECT ID="MyControl" CLASSID="CLSID:0713E8A2-850A-13lb-AXC0-4210302A8DA7" DATA="http://mysite/mydirectory/mydata.xyz" TYPE="application/x-oleobject"> </OBJECT> </BODY> </HTML>
The DECLARE Attribute The DECLARE attribute lets the browser know which object to load and when to load it (after it is referenced). This is a cool feature in two situations--when you have a link point to an object that could not be referenced from a single URL and when one object is a parameter to another object. An example of the latter situation is the ever-popular tree control. The tree control is generally used with a control of images. A tree element of type X has an image that illustrates X and a tree element of type Y has an image that illustrates Y. In order for the image control to be a parameter of the tree control, the tree control lists the image control as a parameter with the PARAM tag (discussed later). The image control then uses the DECLARE attribute so that it is loaded only when the tree control needs it. Loading the control only when it is referenced is called late binding.
Listing 36.6 illustrates how to use the DECLARE attribute. The first control is the tree control, which has a property called ImageList. The # sign in front of the reference to ImageList1 in the tree control indicates that the referenced control is on the same page as the ActiveX control. The ImageList control is the second control that needs to be referenced. The ImageList control must also include the declare statement so that it is loaded only when the tree control is initialized.
If you run this page as it is written in Listing 36.6, it does not run. This code is for discussion purposes only. Using the tree control and the ImageList control actually requires much more code to function than other controls, but these controls are perfect examples of how to use the DECLARE attribute. The tree control and the ImageList use the DATA attribute to initialize the control. I've reduced the value of the DATA attribute so that the code listing is easier to read than it usually is.
<HTML> <HEAD> <TITLE>Declare Attribute</TITLE> </HEAD> <BODY> <OBJECT ID="TreeView1" CLASSID="CLSID:0713E8A2-850A-10lb-AFC0-4210102A8DA7" DATA="DATA:application/x-oleobject;BASE64..."> <!-- referencing the control [daggerdbl] <PARAM NAME="ImageList" VALUE="#ImageList1" VALUETYPE="OBJECT"> </OBJECT> <!-- declaring imagelist [daggerdbl] <OBJECT ID="ImageList1" DECLARE CLASSID="CLSID:58DA8D8F-9D6A-10lb-AFC0-4210102A8DA7" DATA="DATA:application/x-oleobject;BASE64..."> </OBJECT> </BODY> </HTML>
Only two attributes are used to reference the ActiveX ImageList control--NAME and ID. The NAME attribute should be familiar to you. Any information passed in a Form uses the NAME attribute. The NAME attribute is used on the Web server when the page is returned to reference the data sent back. The ActiveX control is used in the same way. If you use the control inside a FORM from which some information is being sent back to the server, the object tag must use the NAME attribute. The name can be any string value you want, such as MyControl or TreeControl, or just CNTR. Listing 36.7 illustrates how to include the NAME attribute on the Web page. The NAME attribute has no effect on any of the other attributes. The browser only uses it to pass values back to the Web server.
<HTML> <HEAD> <TITLE>The Name Attribute</TITLE> </HEAD> <BODY> <FORM METHOD="GET" ACTION="nextpage.htm"> <OBJECT CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" AME="MyControl"> </OBJECT> </FORM> </BODY> </HTML>
Remember that forms use the name/value pair to pass information back to the server. The NAME attribute and the VALUE attribute have to be set. The preceding example is valid according to the HTML specification but will probably not be used in this manner for Internet Explorer 3.x. The problem is that the VALUE attribute is not listed in the object tag, and the browser can't assume that it is any particular attribute. In order to pass back a value to the server in a Form from an ActiveX object, you probably want to set the name and value in VBScript and then include that information in an input tag of the Form tag. The value could be any number of things--a property, a result of a method call, or a value generated as a result of a user event. This functionality may change in the 4.0 version of Microsoft's Internet Explorer.
The other reference attribute is the ID attribute. If you plan to manage the control in script, the ID is mandatory. The only way you can reference the control in script is from the ID. The ID is a string that you choose. Although this string can be just about anything, it is wise to name the ID something that reflects what the control does. Any reference to the control's methods, properties, and events in script has to be prefixed with the ID. (The requirements are the same for the name of the control in a true Visual Basic application.) Listing 36.8 illustrates how you would reference a control from VBScript. Don't concentrate on the syntax of the script; this script is only meant to be an example. A more detailed discussion of VBScript and ActiveX follows later in this chapter in the section "The VBScript Web Page." Notice that Procedure1 changes the background color of the label to green. The object name is Label1 and the property is BackColor.
<HTML> <HEAD> <TITLE>The ID Attribute</TITLE> <SCRIPT LANGUAGE="VBScript"> <!-- Sub Procedure1() Label1.BackColor = "GREEN" end sub --> </SCRIPT> </HEAD> <BODY> <OBJECT ID="Label1" WIDTH=132 HEIGHT=28 CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0"> <PARAM NAME="Caption" VALUE="My Cool Label Control"> <PARAM NAME="Size" VALUE="3493;741"> <PARAM NAME="BorderStyle" VALUE="1"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> </BODY> </HTML>
Several attributes affect how the control appears on the page, including ALIGN, BORDER, HEIGHT, HSPACE, VSPACE, and WIDTH. This section focuses on how these familiar attributes relate to ActiveX controls.
Attribute | Function |
ALIGN | Focuses on the position of the control in relation to the objects around it. The values for align are left, text, middle, textmiddle, baseline, textbottom, center, and right. |
BORDER | Specifies how large the border around the object should be. |
HEIGHT and WIDTH | Specify how large the object should be. |
HSPACE and VSPACE | Specify how much space should be between the control and neighboring objects. |
You have two choices of how to set the parameters of the ActiveX control. The first is through the DATA attribute of the OBJECT tag. The second is through the PARAM tag. The PARAM tag is much easier to use because it follows the HTML standard name/value pair model. The data is not encoded so it is easy to see what has been passed to the control. The PARAM tag is enclosed within the OBJECT's beginning and ending tags.
The PARAM tag has two obvious attributes, NAME and VALUE. NAME is the property of the ActiveX control, which is initialized to the VALUE. The PARAM tag has two more attributes, VALUETYPE and TYPE. The VALUETYPE attribute was used in Listing 36.6 to describe what type of information was contained in the VALUE attribute. The value can be DATA (not encoded), OBJECT (meaning an object's name, as in Listing 36.6), or REF (meaning a Web address reference). The TYPE attribute, which indicates the MIME type of the data, is used in conjunction with the VALUETYPE attribute (when the VALUETYPE attribute is equal to REF). Because the parameter VALUEDATA is a Web site, the browser must know what type of data is being retrieved at that Web site. Listing 36.9 illustrates a couple of different controls that use the PARAM tag. This listing is meant to be an example and may not load in your browser.
<HTML> <HEAD> <TITLE>The ID Attribute</TITLE> </HEAD> <BODY> <OBJECT ID="Label1" WIDTH=132 HEIGHT=28 CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0"> <PARAM NAME="Caption" VALUE="My Cool Label Control"> <PARAM NAME="Size" VALUE="3493;741"> <PARAM NAME="BorderStyle" VALUE="1"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> <OBJECT ID="Marquee1" WIDTH=148 HEIGHT=40 CLASSID="CLSID:1A4DA620-6217-11CF-BE62-0080C72EDD2D" CODEBASE="text.htm"> <PARAM NAME="_ExtentX" VALUE="3916"> <PARAM NAME="_ExtentY" VALUE="1058"> </OBJECT> </BODY> </HTML>
The DATA attribute (encoded data) and the PARAM tag can be used together. However, they rarely are. Most controls use either the DATA attribute or the PARAM tag.
Writing Web pages that have ActiveX controls can be simple if the control is simple. The controls that have great functionality are usually more complex, however. Microsoft has developed an environment that makes writing these pages easier. This tool is called Visual Interdev. It is sold separately or as part of the Visual Developer suite. To illustrate how easy it is to write a Web page with Visual Interdev, I will write a Web page that uses a tab page control.
NOTE: The first control used in this section is Calendar Control 40.0. The OCX file for this control is mscal.ocx . The second control used is Microsoft Forms 2.0 Textbox. The file name is fm20.dll.
First, start up Visual Interdev and insert the control. Figure 36.2 shows the dialog box used to add a new HTML page. To open this dialog box, choose File, New and then select the Files tab. Choose HTML page. After you select these options, Visual Interdev creates a basic HTML file for you and indicates at which point you should start including your own HTML or ActiveX.
FIG. 36.2
Creating a new HTML page is the first thing you do after starting Visual Interdev.
When you want to add an ActiveX control, choose Insert, Into HTML, ActiveX Control. A window of all of the ActiveX controls registered on the system will be displayed. If you have developed a control but it is not displayed in this dialog box, make sure it is registered. Figure 36.3 illustrates the dialog box of all of the controls on this system. The calendar control is highlighted. Notice that behind this dialog box is the HTML file that Visual InterDev has written for you.
TIP: If your control is not registered, you can register it in Visual InterDev from the Tools, Register Control menu item. Or you can go to a command prompt and type regsvr32 x (x is the path and file name of the control). If you just type regsvr32, a dialog box displays all of the options for using the regsvr32 application.
Figure 36.4 illustrates what happens once you choose the control and click OK. The HTML page is still open but is displayed behind the dialog box shown in this figure. The HTML page is where you design the control. You can set the properties displayed in the Properties dialog box or you can resize the object.
FIG. 36.3
The next step is to select the ActiveX control.
FIG. 36.4
You need to design the physical properties and programmable properties of
the ActiveX control next.
The HTML page created when you accept the default properties and don't resize the object is illustrated in Listing 36.10. Notice that Visual InterDev adds Meta tag information. Visual InterDev has completely filled in the calendar control object tag. The default property of the calendar control has no codebase value. In order for this control to download, that attribute needs to be added. The codebase value is not added to any control you choose. You can either add the text to the HTML page yourself or have Visual InterDev do it.
<HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Developer Studio"> <META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1"> <TITLE>Document Title</TITLE> </HEAD> <BODY> <OBJECT ID="Calendar1" WIDTH=288 HEIGHT=192 HSPACE=20 VSPACE=20 ALIGN="CENTER" CLASSID="CLSID:8E27C92B-1264-101C-8A2F-040224009C02" DATA="DATA:application/x-oleobject;BASE64, K8knjmQSHBCKLwQCJACcAgAACADEHQAA2BMAAM0HBAASAA8AAIAAAAAAAACg ABAAAIAAAKAAAQABAAIAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAC8AkRCAQAFQXJp YWwBAAAAkAFEQgEABUFyaWFsAQAAALwCwNQBAAVBcmlhbA== "> </OBJECT> <BR> <OBJECT ID="TextBox1" WIDTH=196 HEIGHT=112 ALIGN="CENTER" HSPACE=20 VSPACE=20 CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3"> <PARAM NAME="VariousPropertyBits" VALUE="2894088219"> <PARAM NAME="Size" VALUE="5186;2963"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> </BODY> </HTML>
It's always best to design the appearance and functions of the Web page before creating it. The Web page being created will display both a text box (ActiveX control) and a calendar (ActiveX control). As a user maneuvers through the calendar, any special information about that day will be displayed in the text box. At this point, I have added the TextBox control. Script needs to be written to handle and trap for the events needed to make the TextBox control contain useful information.
Figure 36.5 illustrates what the page looks like in a browser. No additional text has been added to the page, so you can see what the two controls (the text box and the calendar) look like without having to figure out what goes with the control. The system day and month are chosen. Any month and year can be selected from a drop-down box list. The text box is empty because nothing has been added to it.
FIG. 36.5
The calendar control and the text box could be the foundation for several
Internet applications.
NOTE: Remember that an ActiveX control has properties, events, and methods. A property is a value of the object, such as color or text. An event is a procedure that is triggered when a certain user interaction happens, such as clicking an object. A method can set or get a property value. It can perform a function (such as arithmetic) or fire off an event.
The text box information changes based on user input, so the script must be associated with the events of the control. To add these events, the Visual InterDev Script Wizard (choose View, Script Wizard) should be used. Figure 36.6 is the Script Wizard dialog box. The upper half of the dialog box is divided into two sections. The events are on the left side. The properties and methods are on the right side. The icon for methods is a square with an exclamation point in it. The icon for properties is a square with lines (denoting the property sheet).
The NewMonth event is used to place the text in the text box. The NewMonth event of the TextBox control can be fired off in one of two ways any time the current month is changed. The first way is to change the month in the drop-down list box. The second way is to click a grayed-out day number (the grayed-out number indicates that the day is not in the current month). In order to set the text box, the text box control name has to be referenced. The code in this figure (the entire HTML page) appears in Listing 36.11. Only the DATA attribute has been shortened, although it has not changed from Listing 36.10.
Notice that the Script Wizard has added the required <SCRIPT> tag as well as the code about the NewMonth event that was typed into the event window. You do not need Visual InterDev to write this Web page, but it does make programming ActiveX Web pages easier. The type of script language has to be set in the SCRIPT tag. The two choices are VBScript and Java.
FIG. 36.6
The Script Wizard enables you to write code in either VBScript or JavaScript.
<HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Developer Studio"> <META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1"> <TITLE>Document Title</TITLE> </HEAD> <BODY> <SCRIPT LANGUAGE="VBScript"> <!-- Sub Calendar1_NewMonth() Dim sMonth sMonth = Calendar1.Month TextBox1.Text = "New Month = " & sMonth end sub --> </SCRIPT> <OBJECT ID="Calendar1" WIDTH=288 HEIGHT=192 HSPACE=20 VSPACE=20 ALIGN="CENTER" CLASSID="CLSID:8E27C92B-1264-101C-8A2F-040224009C02" DATA="DATA:application/x-oleobject;BASE64,..."> </OBJECT> <BR> <OBJECT ID="TextBox1" WIDTH=196 HEIGHT=112 ALIGN="CENTER" HSPACE=20 VSPACE=20 CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3"> <PARAM NAME="VariousPropertyBits" VALUE="2894088219"> <PARAM NAME="Size" VALUE="5186;2963"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> </BODY> </HTML>
TIP: If you are not using Visual InterDev or Microsoft ActiveX Control Pad, your ActiveX layout software must have some way of discovering methods, properties, and events. Some controls have documentation, and some don't.
CAUTION: In Listing 36.11, the script code (but not the script tags) are enclosed in the HTML comments <!--" and "-->. If you are writing this code in a different editor than Visual InterDev, you still must include these comments. Several older browsers do not support scripting. The older browser ignores the <SCRIPT> tag and displays the script code as text (because the browser thinks that the script code is text). Microsoft's IE browser treats any VBScript inside the <SCRIPT> tag as script and ignores the fact that this script is HTML commented. This feature lets the page work on different browsers.
When you write a procedure for events, the procedure name must begin with the control ID (ID attribute), followed by an underscore and the event name. In Listing 36.11, the script for the new procedure is Calendar1_NewMonth().Calendar1 refers to the ID attribute of the control, and NewMonth is the event name. Notice that no parameters are passed to this procedure. (They are not passed because the event is triggered by the system.) With this code, the text box displays New Month = 5 for May. Because the control stores months as numbers, the programmer must switch from the numeric representation to the character representation.
Now it's time to add a bit more work to the control. The Web page should be designed so that if a new month or a particular day is chosen, any corresponding information is added. To ensure that the text box information includes the month and the day information, a couple of global variables are added. DayInfo stores the current day's information. MonthInfo stores the current month's information. TextInfo stores the combination of DayInfo, MonthInfo, and anything else added to the text box.
Choose Global Variables from the right side of the Script Wizard dialog box and right-click it. New Global Variable and New Procedure are your options. Choose New Global Variable, type in the name of the month or day, and click OK. Additions to the Web page have only been made in the script section. Listing 36.12 is the new script section. The only added text is the Dim variablename. Dim (short for dimension) is the VB way of defining variables.
<SCRIPT LANGUAGE="VBScript"> <!-- dim MonthInfo dim DayInfo Sub Calendar1_NewMonth() Dim sMonth sMonth = Calendar1.Month TextBox1.Text = "New Month = " & sMonth end sub --> </SCRIPT>
NOTE: Listing 36.12 includes dim and DIM. The global variable dims were written by Visual InterDev's Script Wizard. The DIM in Calendar1_NewMonth() was written outside of the Script Wizard. VBScript doesn't care about the case of the keywords; it is case-insensitive just as Visual Basic is.
TIP: When I first wrote the script for this control, some of the events were not fired when I expected them to fire. To debug this problem, I used the ActiveX control test container to watch the events as they were fired. Figure 36.7 illustrates what the messages look like when the calendar control events are fired.
FIG. 36.7
Use the ActiveX control test container to see events as they are fired off.
Listing 36.13 is the Web page with the code needed to update the text box. It doesn't matter which procedure is first. Figure 36.8 illustrates what the Web page will look like. There is very little code here. But the user can interact with the calendar control, and the test control can be updated.
<SCRIPT LANGUAGE="VBScript"> <!-- dim YearInfo dim MonthInfo Sub Calendar1_NewYear() iYear = Calendar1.Year YearInfo = iYear MonthInfo = Calendar1.Month TextBox1.Text = YearInfo & MonthInfo end sub Sub Calendar1_NewMonth() iMonth = Calendar1.Month select case (iMonth) case 1 MonthInfo = " January is a cold month." case 2 MonthInfo = " February is a snowy month" case 3 MonthInfo = " March is a green month" end select YearInfo = Calendar1.Year TextBox1.Text = YearInfo & MonthInfo end sub --> </SCRIPT>
FIG. 36.8
The calendar control updates the text box based upon the date and month displayed.
There are several types of controls. The last example in Listing 36.13 used a control that "sat" on the page (contained inside the browser window). Some controls can "hover" over the browser, such as the common control dialog (choose File, Open). Some controls are not visible to the user at all. You should look for controls that either add to the functionality of the page or save the user from having to do "extra" work. Adding functionality and helping the user avoid extra work affects the number of visitors that return to your page.
In this example, the Web page has an invisible ActiveX control that reads the system information of the user's machine and fills in a form. The user can then submit the form back to the Web server. If you want to inventory a company's machines but don't want to walk to each machine, add this invisible control to your Web page.
Use the Microsoft SysInfo Control, Version 5.0, with a file name of SYSINFO.OCX. The control needs to be able to read the system information of the user's machine as soon as the Web page is loaded. To do that, use the window_onLoad event. The SysInfo control doesn't have any events or methods--it just has system information properties. As soon as the system information is loaded, you need it to fill in the three text boxes in a form so that the user only has to press the SUBMIT button. This particular form shows the user what is being passed back to the Web server. If the INPUT tags were of type HIDDEN, the user would never have known that the information was being passed back.
Listing 36.14 includes the entire contents of the Web page. Figure 36.9 shows how the page loads in the browser. To load the text boxes of the form when the page is first loaded, the window_onLoad procedure needs to have the name of the text box. Because the text box is in an INPUT tag, and the INPUT tag is in a form, the name of the text box is FORM.ELEMENT.VALUE. The INPUT tag is set directly by the SysInfo control's properties. And that is all there is to this simple procedure.
<HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Developer Studio"> <META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1"> <TITLE>Document Title</TITLE> <SCRIPT LANGUAGE="VBScript"> <!-- Sub window_onLoad() MySysInfoForm.InputSysBuild.value = SysInfo1.OSBuild MySysInfoForm.InputSysPlatform.value = SysInfo1.OSPlatform MySysInfoForm.InputSysVersion.value = SysInfo1.OSVersion end sub --> </SCRIPT> </HEAD> <BODY> Thank you for visiting my page. Here is your system information. <OBJECT ID="SysInfo1" WIDTH=39 HEIGHT=39 CLASSID="CLSID:6FBA474B-43AC-11CE-9A0E-00AA0062BB4C"> <PARAM NAME="_ExtentX" VALUE="1005"> <PARAM NAME="_ExtentY" VALUE="1005"> <PARAM NAME="_Version" VALUE="327680"> </OBJECT> <FORM ACTION="sysinfo.asp" METHOD="GET" NAME="MySysInfoForm"> <INPUT TYPE=TEXT NAME="InputSysBuild"> Build Number<BR> <INPUT TYPE=TEXT NAME="InputSysPlatform"> Platform<BR> <INPUT TYPE=TEXT NAME="InputSysVersion"> System Version<BR> <INPUT TYPE=SUBMIT NAME="SUBMIT"> </FORM> </BODY> </HTML>
FIG. 36.9
System information of the visitor is displayed in a Web page.
The last example uses the CommonDialog control, which "hovers" over the browser window. In this example, the event is fired from inside a button, which is inside a form. No separate VBScript section is needed. The onClick event of the button contains the code. The code must display the dialog box and then set the text box with the file name. Both of these actions happen within the onClick event.
Listing 36.15 illustrates how easy it is to make these activities happen. The first thing the onClick event does is to pop up the dialog box in order to find the file, CommonDialog1.ShowOpen(). Next, the onClick event assigns the file chosen to the text box in the form, FINDFILE.strFile.value. The objects in the form should have names. Figure 36.10 illustrates this Web page when the file is being chosen.
<HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Developer Studio"> <META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1"> <TITLE>Document Title</TITLE> </HEAD> <BODY> Step 1) Please find the file you want to send to the server. <FORM NAME="FINDFILE"> <INPUT LANGUAGE="VBScript" TYPE=BUTTON ONCLICK="call CommonDialog1.ShowOpen() FINDFILE.strFile.value = CommonDialog1.FileName" AME="bFINDFILE" VALUE="Find File"><P><P> Step 2) You choose <INPUT TYPE=TEXT NAME="strFile"> </FORM> <OBJECT ID="CommonDialog1" WIDTH=32 HEIGHT=32 CLASSID="CLSID:F9043C85-F6F2-101A-A3C9-08002B2F49FB"> <PARAM NAME="_ExtentX" VALUE="847"> <PARAM NAME="_ExtentY" VALUE="847"> <PARAM NAME="_Version" VALUE="327680"> <PARAM NAME="DefaultExt" VALUE="*.*"> <PARAM NAME="DialogTitle" VALUE="My Common Dialog Control"> <PARAM NAME="InitDir" VALUE="c:\"> </OBJECT> </BODY> </HTML>
Please don't try to use any controls that have been downloaded to your machine from the Web except on the Web page they were downloaded with. They may be from reputable software manufacturers, such as Microsoft, or they may be written by an individual. In either case, you cannot guarantee what the control will do, and the only "documentation" you have for that control is your discovery of it for properties, methods, and events.
Any control downloaded from the Web should be treated with the same respect as a shareware product unless it is Verisigned. Verisign authentication means the code and company have been registered and can be held responsible for the behavior of their ActiveX component. If the control does not have a Verisign authentication, you have no way of knowing who wrote it or to what extent it functions.
FIG. 36.10
Find the file by using the CommonDialog control.
http://www.microsoft.com/gallery.asp If you want to ensure a quality Web site and experience for your users, either purchase a control (there are several well-respected manufacturers) or make your own. A list of ActiveX control manufacturers can be found at a site known as the ActiveX Gallery.
Do not assume that a control that comes from Microsoft is of Microsoft quality. Microsoft has delegated the development of controls to third-party companies, such as those listed in the ActiveX Gallery. The controls in the Gallery that come from Microsoft are meant to have low functionality, and they generally have no support.
You may be under the impression that the controls are free because you are not charged for them when they are downloaded to your machine. That is incorrect. Just because a control comes from the Web does not mean it is free. ActiveX components are purchased and used the same way as any other software.
JavaScript is a scripting language that you write along with the HTML in your Web pages to do the same kinds of tasks you do with VBScript. These two scripting languages have essentially the same capabilities and can be used to accomplish the same tasks. The only difference between them is in the languages themselves. You know that VBScript is a subset of Visual Basic. It is very familiar to those who are used to programming in Visual Basic. JavaScript, on the other hand, is loosely based on Java, which, in turn, is loosely based on C++. So if you come from a C++ or Java background, you will probably prefer JavaScript.
You may have heard that JavaScript is a "simplified Java." It is not. It is a completely different language, which is designed specifically for scripting tasks and is only loosely based on the Java language.
Can you do everything you want to do with Visual Basic? Maybe, but think about these questions: Do you want to be able to use controls and applications written by others? Is the ability to run your applications on more than one platform important? If you answered yes to either of these questions, you definitely need to give Java a second look.
Java can be compiled and used to create stand-alone applications just as Visual Basic and C++ can create stand-alone applications. But Java can also be used to create Java applets. An applet, as the name implies, is a small application that can be downloaded when a browser pulls up your Web page. Once the applet is downloaded, the applet is executed and the results appear on your page. These results might show up in the form of an animation, a mortgage calculator, or a game.
So what's the difference between a Java applet and an ActiveX control? Functionally, there isn't much of a difference. You can use both to enhance and activate your Web pages in a variety of ways. But there is a big difference in the way they are implemented.
First, Java applets are always written in Java. ActiveX controls can be written in any language. Second, ActiveX controls are generally platform-specific to Windows (generally because you can write ActiveX controls in Java). But even when ActiveX controls are written in Java, you cannot automatically use them wherever you use Java applets. ActiveX controls are built on top of Microsoft's COM Architecture, which is built into Windows. This architecture needs to be in place before the ActiveX control can work. Fortunately, the COM Architecture has been ported to the Macintosh and to some flavors of Unix. Therefore, everywhere you have the COM Architecture, you can port Java-written ActiveX controls.
Java applets don't have any inherent dependence on architecture as do ActiveX controls, but they do sometimes make use of platform-specific libraries. If you use a user-interface library for your Java applet that was written exclusively for Windows, then you've negated the multiplatform benefit of Java. Although many libraries strive to be multiplatform, you still have to be careful what libraries you use.
So which language is better? That depends on who you ask. Java proponents could emphasize the multiplatform benefits of the applet, while ActiveX proponents could point both to the higher level of integration that an ActiveX control provides and to the proven success of the ActiveX (formerly OLE) architecture in Windows applications.
In the final analysis, you probably want to be able to work freely with both ActiveX controls and Java applets when you create your own Web pages. Fortunately, it isn't difficult to do so.
Up until now you have focused your attention on creating Web pages that use ActiveX controls. This is not the only way that feature-rich Web pages can be created. Java applets can provide your Web page with a broad range of creative expression. In the following sections you see just how easy it is to use Java applets on a Web page.
You are familiar with the <OBJECT> tag that is used to insert ActiveX controls into your HTML document. There is a different tag for Java applets: <APPLET>.
<APPLET CODEBASE="applets/java" CODE=CardGame.class WIDTH=150 HEIGHT=220 ALIGN=LEFT ALT="The Card Game" ID=game> </APPLET>
The following list describes the different components of the preceding example:
Other interesting properties are also available:
There is often nothing between the <APPLET> tag and its ending tag. You can create Java applets that accept parameters from the Web page. These parameters are specified between the beginning and ending tags in this form:
<PARAM NAME="parametername" VALUE="value">
There can be any number of <PARAM> tags between the begin and end <APPLET> tags. The name of the parameter is specified using the NAME property, and the value you give the parameter is assigned to the VALUE property. Again, the Java applet must be designed to accept parameters before you can pass them.
The </APPLET> ending tag is required.
You can access and manipulate Java applets right from your VBScript code in almost exactly the same way that you access ActiveX controls:
<SCRIPT language = "VBScript"> <!-- Sub Document_OnLoad document.game.DealCards End Sub --> </SCRIPT>
The preceding code calls the function named DealCards in the Java applet that is inserted into the Web page in the last section. You must always prefix the name of the applet with the word document. You can refer to any public property or call any public function in the class.
You cannot simply insert an applet into your page and begin manipulating it from VBScript. The applet must be designed to allow you to take advantage of its capabilities.
There are several requirements for designing the applet. First, if you create the class in Java, you must inherit that class from the applet class. If you want to make properties and methods from other classes available, you must create wrapper properties and methods in the applet-derived class and then delegate to the properties and methods of the other classes.
Second, you must make all of the properties and methods you want access to in VBScript public. All public properties and methods of your applet-derived class can be manipulated in VBScript.
Finally, the parameters that can be specified in the <APPLET> tag are not the same as the public variables that can be manipulated by VBScript. In order to make use of parameters, you must use the getParameter() function.
The Java applet's name is scoreboard.java. The applet displays a number in big, bold text. The idea is that you can create a game using VBScript and other Java or ActiveX controls and then use this applet to display the current score.
Listing 36.17 is the source code for the scoreboard applet.
import java.applet.*; import java.awt.*; public class scoreboard extends Applet { public int score=0; public void updatescore() { repaint(); } public void paint(Graphics g) { Font fnt = new Font("Helvetica", Font.BOLD, 24); g.setFont(fnt); g.drawString(String.valueOf(score), 20, 20); } }
If you know Java, you can easily understand how this applet works. If you don't, teaching you Java is well beyond the scope of this chapter. Even if you've never seen Java code before, you should be able to follow along how this applet works.
The first two lines, which are needed by the applet, include some standard Java libraries. The libraries enable you to create an applet and to use input/output commands.
The next line creates a new class called scoreboard, which is inherited from the class named applet. All applets are descendants of the applet class or one of applet's descendants. The rest of the listing fills in the details about this new scoreboard class. You know this is the case because all of the rest of the code is wrapped between the curly brackets ({ and }).
The next line creates a public integer variable named score that is initialized to 0. This is the variable that always holds the current score. Again, notice that the variable is public; therefore, it is available to you when you write your VBScript code.
Next, a public function is created called updatescore. The void indicates that the updatescore() doesn't return a value, and the empty parentheses after the void indicates that this function doesn't expect any arguments. All the updatescore() does is to call the repaint() function. This action causes the applet to repaint itself and to execute any code in the paint function.
The last function is the paint function. This function is automatically called by the system whenever the applet is repainted, which happens when the applet is first loaded into the page and any time the repaint() function is called. This function accepts a argument that identifies the graphic workspace on the applet. This workspace is where you print the score.
The code in the paint function first creates a font object with a bold, Helvetica, 24-point font. That object is then passed to the setFont() function to make it the current font. Finally, the drawString() function is called. The number contained in the score variable is converted to a string and passed to the function to be printed. The 20, 20 indicates the part of the applet on which the text appears.
Note three key things about this simple applet. First, it defines a class that is descended from the applet class. VBScript can only access variables and functions from descendants of the applet class.
The other two things you should notice are the public variable score and the public function updatescore. Because these are public, you should be able to call them from VBScript.
In order to put this applet to work, you need a Web page. Listing 36.18 shows a sample page.
<HTML> <HEAD> <TITLE>Game</TITLE> </HEAD> <BODY> <h1>Game</h1> The Score Is:<p> <APPLET CODE="scoreboard.class" CODEBASE="d:\javaproj\game" ID=sign WIDTH = 70 HEIGHT = 30> </APPLET> <p> <INPUT TYPE=button VALUE="Score + 10" NAME="BtnScoreTen"> <SCRIPT LANGUAGE="VBScript"> <!-- Sub BtnScoreTen_OnClick document.sign.score = document.sign.score + 10 document.sign.updatescore End Sub --> </SCRIPT> </BODY> </HTML>
This sample page is very basic. It just shows you how to drop the applet into a Web page and how to work with it. You could easily expand on this page to form the heart of an interesting Web application.
Notice the <APPLET> tag. It identifies the name of the class that uses the CODE attribute and where on your system that code might be found. An appropriate WIDTH and HEIGHT are specified. Even more importantly, the applet is given an ID for VBScript to use when it references the applet.
A simple form-style button is then used to kick off the BtnScoreTen_OnClick VBScript subroutine. The number in the applet's score variable is increased by 10. And the updatescore function is called so that the user can see the change. Notice that the document and then the applet name are specified in order to qualify the applet variable and the updatescore function.
When you bring up the page, you see a box holding the number 0. Every time you click the button, the score is increased by 10. Nothing to it!
Java applets provide you with an alternative to using ActiveX controls to activate your Web pages. Each of these methods has advantages and disadvantages when weighed against the alternative method. Fortunately, you don't have to choose one or the other. You can use both very easily and from VBScript's perspective, almost seamlessly. This seamless interaction gives you the flexibility to design your Web page so that it is both dynamic and content-rich, no matter what browser you use to view it.
Before you design a Web page to include an ActiveX control, you should check out a few things. Make sure the page is gaining information from the client. If you are performing a function that can be done just as easily on the Web server, then it should be done there. But if you want to jump into writing ActiveX Web pages, first get the documentation for the controls and a good editor (such as Visual InterDev).
For related material on ActiveX, see the following chapters:
© Copyright, Macmillan Computer Publishing. All rights reserved.