Полезная информация

Chapter 15
Testing and Using Your Components


Testing and Using Your Components

Once you have created your ActiveX component, the next step is to use and test your component. You will not typically wait to try out your component until after it is completely implemented. More than likely, the first thing you will want to do is compile your code and try to use your component before you've added any significant functionality. You need to be aware of the types of container and testing applications that are available to you as a developer.

Even more critical than the actual testing of the component is testing it as soon as possible. Even with all of the banners being raised about reuse and compatibility, there are still issues to be aware of, which depend upon the tools you use. Some containers or tools may not support the features that your component supports, and even worse, in some cases, container implementations may differ, resulting in slightly different behavior. What may work in VB may result in a crash in VC++. A word of advice: Test your components often and with all of the tools that you plan to use your components with.

This chapter will focus on the types and numbers of tools available that can host ActiveX Controls, as well as the tools that you can use to test your controls. Even though the primary focus of the chapter is on ActiveX Controls, almost all of the applications mentioned can launch and use ActiveX Automation Servers and even ActiveX COM objects. Because there are so many and they change so rapidly, it is beyond the scope of this book to address all of the ActiveX capabilities of all the tools available to you. You will need to research the specific tool to see to what extent it supports ActiveX and COM.

ActiveX Containers and Controllers

Applications that use ActiveX controls are called container applications, or just containers. In this chapter, you will discover how to use your control in Microsoft Visual Basic, Microsoft Visual C++, Web browsers, Microsoft ActiveX Control Pad, and the Microsoft Office tools: Access, Word, and Excel. Visual Basic is probably the easiest tool to use, and Visual C++ is probably the hardest. This chapter will explain how to insert an ActiveX control into these containers, how to change the control's properties, and how to code the events contained in the control.

NOTE: If a container application is to be distributed, all controls added to a container must be distributed with the container.

Using Visual Basic as a Container

To place a control in a Visual Basic application, you can open an existing project or create a new one. To create a new project, select File, New Project from the Visual Basic menu, select Standard EXE from the New Project dialog, and click the OK button. To open an existing project, select File, Open Project from the Visual Basic menu. If you want to open a recent project, select the Recent tab, select the desired project from the File list box, and click the Open button. If the project you are looking for is not listed on the Recent tab, select the Existing tab, and then select your project from the proper directory. After you have selected the project, click the Open button to open the project.

Next you need to create a form or open an existing one. To create a form, select Project, Add Form from the Visual Basic menu. If the Add form dialog appears, click Form on the New tab, and then click the form in the project window. To open an existing form, click the form in the project window, and then click the View Form button.

Now you need to add the control to the project. Select Project, Components from the main menu, which brings up the Components dialog (see fig 15.1). Make sure that the Selected Items Only check box, on the lower-right side of the Components dialog, is not selected. The Selected Items Only option will limit the display to the items previously selected. Search for the name of the control you want to add on the Controls tab, and click the check box next to the control. To see the path of a particular control, click the control name, and the path will display in the frame at the bottom of the dialog.

FIG. 15.1
Select
Project, Components to display the Components dialog.

If the control is not registered, it will not appear on the Controls tab. To select an unregistered control, click the Browse button, select your control from the proper directory, and click the Open button to register your control.

After the control is checked, click the Apply button to add the control to the Toolbox, and then click the OK button to close the Components dialog. If the control file added contains more than one control, you will see more than one tool added to the Toolbox. If the MFCControl control was added, you will see three new tools, labeled with a purple OCX. If each control had a different icon, you would see three different icons on the Toolbox. If you drag the mouse over the icons on the Toolbox, tool tips appear to tell you which control you are selecting. To place the control on the form, double-click the new tool button or click the new tool button, and then click and drag the form. If the toolbox is not displayed, select View, Toolbox from the Visual Basic menu.

To set the properties at design time, you need to use the Properties grid located on the right side of the screen, which lists all the changeable properties and their current values. If the Properties grid is not displayed, click the control on the form, and press F4 to display the Properties grid. The left column contains the property names, and the right contains the current property values. Click the Alphabetic tab on the Properties grid to list the properties alphabetically, or select the Categorized tab to view the properties by property category. To change a value, click the cell containing the name of the property you want to change, and then click property value cell in the same row and edit the value.

Setting the properties in code is almost as easy. To set a control in code use following syntax:

ControlName.PropertyName = Value

ControlName is the name of the control, PropertyName is the name of the property, and Value is the new property value or a variable containing the value.

Retrieving a property value is the reverse of the preceding:

Variable = ControlName.PropertyNameVariable in this case is used to hold the value of the property.

To execute the methods of the control, use the following syntax:

Variable = ControlName.Method Parameter1,...ParameterN

Variable is the name of the variable that will hold the return value of the method. If the method has no return value, Variable and the = will be eliminated. ControlName is the name of the control, Method is the name of the method, and Parameter1,...ParameterN represents any parameters to be passed to the method.

The final step in the design process is coding the events. To code an event, follow these steps:

  1. If the Project Explorer window is not visible, Select View, Project Explorer. The Project Explorer window appears.

  2. Select the form that contains the control, and then select View, Code to display the Code window (see fig. 15.2).

    FIG. 15.2
    Select
    View, Code from the Visual Basic menu to display the Code window.

  3. Select the control you want to add the event code for from the Object combo box, which is the combo box on the left.

  4. Select the event you want to code from the Procedure combo box, which is the combo box on the right.

  5. Enter the code between the Private Sub and End Sub statements.

Repeat Steps 4 and 5 to code any of the other events contained in the control.

If you change your control, don't forget to recompile your Visual Basic executable to prevent errors.

You can find more information on using ActiveX controls in Visual Basic in the Visual Basic help files or the Knowledge Base articles on Microsoft's Web site (http://www.microsoft.com/kb/).

Using Microsoft Visual C++ as a Container

The easiest way to use your control in a Microsoft Visual C++ application is to use the Microsoft Foundation Classes (MFC) with a dialog. When you first create an application that will be using ActiveX controls, be sure to check the ActiveX Controls option in Step 3 of the MFC AppWizard (see fig. 15.3). If you do not select this option, you will have to add a call to AfxEnableControlContainer in the application's InitInstance member function (see fig. 15.4).

FIG. 15.3
Here is where you check the ActiveX Cont
rols option.

FIG. 15.4
You add a call to AfxEnableControl Container in the application's InitInstance member function.

To add your control to a dialog, follow these steps:

  1. Select the ResourceView tab of the Project Workspace window, click the "+" next to the project's resources folder, click the "+" next to the Dialog folder, and then double-click the ID for the dialog. These steps will display the dialog in the Dialog Editor window.

  2. From the Project menu, select Add To Com_ponents and Controls to display the Components and Controls Gallery dialog (see fig. 15.5).

    FIG. 15.5
    Select
    Project, Add To Project, Components and Controls to display the Components and Controls Gallery dialog.

  3. Double-click the Registered ActiveX Controls folder to display a list of ActiveX controls.

  4. Scroll through the list of controls to find the icon for your control. Select the icon and click the Insert button to add the control to your dialog, which will bring up a message box asking "Insert this component?" Click the OK button. This will bring up the Confirm Classes dialog.

  5. Click the OK button to generate the wrapper class and to add the control to the Controls Toolbar; the Confirm Classes dialog will close automatically. The wrapper class serves as an interface between your application and the control.

  6. Click the Close button on the Components and Controls Gallery dialog.

  7. Click and drag the control from the Controls Toolbar to the dialog to place the control on the dialog.

To set the properties of the control at design time, click the control on the dialog, and select View, Properties from the Developer Studio menu. The Control Properties dialog will appear (see fig. 15.6). Click the Keep Visible Pin to keep the dialog from closing. A property tab is available for General properties, All properties, and any property pages you defined in your control. General properties are the base set of properties assigned to all controls on the dialog. All properties are stock properties you defined in the control. To change a property value, click the tab containing the name of the property you want to change, and then set the value for the property.

FIG. 15.6
Use the Control Properties dialog to set the properties for the control.

The easiest way to access the properties and methods of the control in code is to create member variables that coincide with the control. To create the member variables, follow these steps:

  1. Select View, ClassWizard to display the MFC ClassWizard dialog.

  2. Select the Member Variables tab.

  3. Make sure the Dialog class appears in the Class name text box.

  4. In the Control IDs list box, select the ID for the control.

  5. Click the Add Variable button to add the member variable. The Add Member Variable dialog appears.

  6. In the Member variable name text box, enter a name for the member variable. A good naming standard is to enter the control name prefaced with m_.

  7. Make sure the Category combo box still contains "Control," and click the OK button. The other choices are for the control's exposed properties.

  8. Click the OK button on the MFC ClassWizard dialog to accept the member variable. ClassWizard defines the member variable in the dialog class and adds a Dialog Data Exchange (DDX_Control) call to the dialog's implementation of the DoDataExchange function.

Now that the member variable is created, setting and retrieving properties and executing methods is fairly simple. Manipulating the properties requires using the functions in the wrapper class designed to do so. These functions are added to the wrapper class by ClassWizard. In the MFCControl control, the functions to use for setting properties include SetBackColor, SetAlignment, and SetCaptionProp. The functions for retrieving properties include GetReadyState, GetBackColor, GetAlignment, and GetCaptionProp. To use these prop- erty functions, you use the following syntax:

Variable = WrapperClassVariable.Function (Parameter1,...ParameterN).

Variable is used to hold a return value from the function; this will not be used if there is no return. WrapperClassVariable is the wrapper class variable ClassWizard defined in the dialog header file. Function is the name of the function being used to retrieve or set the property, and Parameter1,...ParameterN represents parameters that need to be passed to the function.

Executing a method is basically the same as calling a property function. To execute a method, use the following syntax:

Variable = WrapperClassVariable.MethodName(Parameter1,...ParameterN)

Variable is used to hold a return value if the method returns a value. Again, WrapperClassVariable is the wrapper class variable ClassWizard defined in the dialog header file. MethodName is the name of the method you want to execute, and Parameter1,...ParameterN represent parameters that need to be passed to the method.

Okay, now for coding the events. If you have ever created event handlers for a button, radio button, or any other standard control in a dialog, you already know how to set up event handling for your custom control; the setup is the same. You use the Message Maps tab of the ClassWizard to create an event sink map, which is basically an outline, or map, of event handlers maintained by ClassWizard. When your control fires an event, the event handler that is mapped to that event is executed.

To create an event handler for an event, use the following steps:

  1. Select View, ClassWizard to open the MFC ClassWizard dialog.

  2. Select the Message Maps tab if it is not the current tab.

  3. Make sure the Dialog class appears in the Class name text box.

  4. Select your control from the Object IDs list box. The Messa_ges list box now shows the events for the control (see fig. 15.7).

    FIG. 15.7
    Messages list box shows the events for the control selected in the Object IDs list box.

  5. In the Messa_ges list box, select the event you want to add code for.

  6. Click the Add Function button to bring up the Add Member Function dialog. The Member function name text box contains a suggested name for the handler function. You can change the name if you like. Click the OK button when finished. If you look at the Member functions list box, you will see the new event handler function listed. The uppercase "E" in the gray box signifies that this is an event handler.

  7. To add code to the handler, click the Edit Code button, which will dump you into the event handler function for that event. Add your code for the event here.

More information about adding controls to Visual C++ applications can be found in the Visual C++ help files and Microsoft's Knowledge Base (http://www.microsoft.com/kb).

HTML and Web Browsers

Using your control in an HTML (Hypertext Markup Language) page consists of basically three actions: placing the control in the HTML, downloading the control to the user, and installing the control on the user's machine.

If all your Internet users are using the Microsoft Internet Explorer, the task of inserting an ActiveX control in an HTML document is fairly simple. If your users are using Netscape Navigator, or both, inserting a control requires a little more work.

The Microsoft Internet Explorer requires the use of the <OBJECT> HTML tag, which Netscape has not yet adopted. This tag is composed of several attributes, the most important being ID, CLASSID, CODEBASE, PARAM NAME, and VALUE. Listing 15.1 shows the HTML code that might be used with the MFCControl control.

Listing 15.1 SAMPLEIE.HTM--Using an ActiveX Control in HTML Code

<HTML>
<HEAD>
<TITLE>Sample Page</TITLE>
</HEAD>
<BODY>
<OBJECT
ID="MFCControlWin1"
WIDTH=100
HEIGHT=51
CLASSID="CLSID:A1198546-2E75-11D0-BD82-000000000000"
CODEBASE="http://www.somesite.com/somedirectory/ MFCControl.ocx">#Version=1,0,0,1">
<PARAM NAME="Alignment" VALUE="1">
<PARAM NAME="CaptionProp" VALUE="Sample">
</OBJECT>
</BODY>
</HTML>

The ID attribute gives the control a name, providing a way for the HTML code to access the control.

The CLASSID attribute, which is the unique UUID assigned to the control, tells Microsoft Internet Explorer which object to load. The UUID for your control can be found in the ODL (Object Description Library) file for your ActiveX control. Be sure to locate the UUID for the specific control you are using by looking for the class information comment for the control. For example, to locate the UUID for the MFCControlWin control used above, you would look for the following:

// Class information for CMFCControlWinCtrl
[ uuid(A1198546-2E75-11D0-BD82-000000000000),
helpstring("MFCControlWin Control"), control ]

Open the ODL file with Notepad or something similar, copy the UUID from there, and paste it in the HTML document.

NOTE: Even if you have only one control in your OCX file, this file contains many UUIDs. Be sure to locate the proper UUID using the method above. Also, your UUID will not be the same as the one in the example.



If the current version is not on the user's machine, the CODEBASE attribute tells Microsoft Internet Explorer where to find the control to download. Once the current version is loaded on a user's machine, the HTML document uses the control from the user's machine, allowing the document to load faster. Keep in mind that if your control was built with the Microsoft Foundation Classes, the MFC DLLs have to be loaded on the user's machine. This adds to the size and complexity of the download. The bigger the download, the longer the user has to wait to load the control. If your control is built using the BaseCtl, the CODEBASE statement refers to the control only. If you created your control with MFC, you need to use a new technology from Microsoft called Cabinet files (CAB files for short). These files allow you to compress a group of files into one file (the CAB file), download the file to the user's PC, and install the files on the user's PC. The CAB file contains an INF file, which controls the installation. Check out Microsoft's Web site (http://www.microsoft.com/) and the ActiveX SDK documentation for more information on CAB files.

NOTE: Even if you created your control without the Microsoft Foundation Classes, you can still use a CAB file to compress your control and save transfer time.



The <PARAM> tag is used inside the <OBJECT> tag to set the initial property values of the control. The <PARAM> tag has two attributes: NAME and VALUE. The NAME is the name of the property, and the VALUE is the property value.

Netscape Navigator users will need to purchase a plug-in from NCompass Labs called ScriptActive. This plug-in allows Navigator to run HTML documents that contain ActiveX controls. The information to be used by this add-in is contained in an <EMBED> tag because Navigator does not recognize the <OBJECT> tag. If your Web page will be read using Netscape Navigator and Microsoft Internet Explorer, which is most likely the case, nest the <EMBED> tag within the <OBJECT> tag. Microsoft Internet Explorer will fail if the <EMBED> tag is outside the <OBJECT> tag. ScriptActive comes with the HTML Conversion Utility, which creates a Netscape HTML file from a Microsoft Internet Explorer HTML file, making the developer's life easier. Create your page with ActiveX Control Pad and use the utility to automatically create a page compatible to both browsers. The HTML document (see Listing 15.2) is an example of a document converted by the HTML Conversion Utility. Visit the NCompass Labs Web site (http://www.ncompasslabs.com/ )for more information.

Listing 15.2 SAMPLENN.HTM--Converted HTML Document

<HTML>
<HEAD>
<TITLE>Sample Page</TITLE>
</HEAD>
<BODY>
<OBJECT
ID="MFCControlWin1"
WIDTH=100
HEIGHT=51
CLASSID="CLSID:A1198546-2E75-11D0-BD82-000000000000"
CODEBASE="http://www.somesite.com/somedirectory/
MFCControl.ocx#Version=1,0,0,1">
<PARAM NAME="Alignment" VALUE="1">
<PARAM NAME="CaptionProp" VALUE="Sample">
<EMBED
NAME="MFCControlWin1"
WIDTH=100
HEIGHT=51
CLASSID="CLSID:A1198546-2E75-11D0-BD82-000000000000"
CODEBASE="http://www.somesite.com/somedirectory/MFCControl.ocx#Version=1,0,0,1"
TYPE="application/oleobject"
PARAM_Alignment="1"
PARAM_CaptionProp="Sample"
></OBJECT>
</BODY>
</HTML>

Another powerful attribute is SCRIPT. This attribute allows a developer to add code directly to an HTML document. Currently, two scripting languages are available: JavaScript and Visual Basic Script (often referred to as VBScript), which imitate Java and Visual Basic, respectively. Check out Netscape's Web site (http://home.netscape.com/) for JavaScript syntax and information and Microsoft's Web site (http://www.microsoft.com/) for VBScript syntax and information. Chapter 16 explains scripting in a little more detail.

NOTE: Unless you have certified your control, make sure that the Safety Level is not set to High in Microsoft Internet Explorer. If it is set to High and your control is not certified, it will not run your scripts. To check or change this setting, select View, Options from the Explorer menu. Select the Security tab, and then click the Safety Level button to display the Safety Level dialog. Most users, especially developers, choose Medium because it gives you the option to load or not load something. Certification and other security issues are covered in Chapter 16.

ActiveX Control Pad

The number of Web Authoring tools is growing rapidly; very little manual coding of HTML is done anymore. The ActiveX SDK includes a handy little tool called the ActiveX Control Pad, which aids in managing ActiveX controls in Web pages. It allows you to easily add controls and create VBScript and JavaScript scripts. It also integrates a WSIWYG design area for authoring 2-D layouts in conjunction with Microsoft's HTML Layout Control.

When you first bring up Control Pad, it creates an initial blank HTML document and opens the document in the Text Editor (see fig. 15.8).

FIG. 15.8
When you first bring up Control Pad, it creates a blank HTML document.

To insert an ActiveX Control, select Edit, Insert ActiveX Control, which opens the Insert ActiveX Control dialog. This dialog displays a list of all registered ActiveX controls. Select the control you want to insert from the Control Type list box on the Insert ActiveX Control dialog, and click the OK button. A form displaying the control appears along with a Properties grid. Use the mouse to size the control.

NOTE: Version 1.0 of the ActiveX Control Pad has some bugs in its refreshing functionality. Once in a while, items appear to smear when you are sizing or positioning them, but they aren't. Once you close the editor in use and open it again, things are back to normal.



Set the initial values of the properties using the Properties grid. Select the property you want to change, and then enter the new value at the top of the Properties grid. After you have entered the new value, click the Apply button to save the setting. When you exit the form, the necessary HTML is generated and added at the current cursor position. Figure 15.9 is an example of HTML code generated with the ActiveX Control Pad.

FIG. 15.9
HTML is generated for the added control.

This method of inserting an ActiveX control works fine if you don't care where the control or controls are placed, but if you want the control(s) at specific X and Y coordinates, you need to use an HTML layout because HTML currently cannot recognize X, Y, and Z order positioning. HTML layouts allow exact positioning of controls on a Web page. The ActiveX Control Pad saves the HTML layout in a file with an ALX extension. When a browser reads the HTML that contains an HTML layout, it loads the HTML layout from the ALX file. Control Pad provides the HTML Layout Control for creating and editing these layouts. The HTML Layout Control gives the developer a forms-based Web page development environment similar to the Visual Basic interface.

To create an HTML layout, select File, New HTML Layout to open the HTML Layout Editor. You can click and drag any of the default controls on the Standard or Additional tabs onto the form. To set the properties, select View, Properties to display the Properties grid.

To add your ActiveX control, click the right mouse on the bottom of the tab in the Toolbox where you want the control to reside, and select Additional Controls to bring up the Additional Controls dialog (see fig. 15.10).

FIG. 15.10
The additional Controls dialog lists all registered ActiveX controls.

Select the control you want to add by clicking the check box next to its name in the Available Controls list box. Click the OK button to add the control to the tab, and close the Custom Controls dialog. Now you can use that control as if it were part of Control Pad.

After you have your controls set up, close the form and save the changes. This course returns you to the HTML Source Editor. Now that you have created the layout, you need to add it to the HTML. Click an insertion point anywhere inside the <BODY> tags, and then select Edit, Insert HTML Layout. Select the layout you want to insert, and then click the OK button. The needed HTML will be generated and placed at the cursor.

The Control Pad is also helpful for creating scripts. Before creating a script, make sure you set the Script Language for the page. Select Tools, Options, Script to bring up the Script Options dialog. Select the scripting language you prefer, and then click the OK key to save your selection.

To create the script, open the Script Wizard by selecting Tools, Script Wizard. Scripts can be created using the List View or the Code View. List View allows you to insert actions while Code View is more of a code editor. To create a line of code, select an event from the Select an Event list box. This selection determines which event the script is being created for. After the event is selected, select an action, and double-click it to insert it into the script. If you are in List View, you will be prompted to enter any needed parameters for the selected action. If you are in Code View, a skeleton of the needed command will appear in the Script Pane; you will need to edit the necessary pieces. You can also add code in the Script Pane.

When you are finished creating the necessary scripts, click the OK key to add the scripts to the HTML code.

For more information on Control Pad, refer to Control Pad's help files and the Author/Editing section of Microsoft's Web site.

Using the Microsoft Access, Word, and Excel Applications as ActiveX Control Containers

When you design a control, you probably think, "It has to work in Microsoft Visual C++, Microsoft Visual Basic, and on the Internet." What about Office products? For example, what if someone wants to use a fancy list box control you've created in a Microsoft Word Document to list the sections of a long document, allowing the users to pick the section they want to jump to. Microsoft Office 97 makes it easy to use an ActiveX control in an Office application, even in Microsoft Word. ActiveX controls can be a very useful addition to Microsoft Office 97, especially in Microsoft Access, Microsoft Word, and Microsoft Excel.

So how do you add controls to these products? The Microsoft Access menu choices are a little different than Microsoft Word and Microsoft Excel, but the concepts are the same. Basically, you choose More Controls from the Controls Toolbox, select your control from the list, set the properties, and add code to the events.

To add a control to a Microsoft Access form, follow these steps:

  1. To open or create a new form, click the Forms tab of the Database window, which appears when you first open an existing database or create a new one. To create a new form, click the New button. This action opens the New Form dialog. Select Design View from the list box, and click the OK button. To select an existing form, select the form from the list of forms on the forms tab of the Database window, and then click the Design button on the Forms tab. This action opens the form in Design View.

  2. If the Toolbox is not visible, select View, Toolbox from the Access menu to display it (see fig. 15.11).

    FIG. 15.11
    Note the More Controls icon at the bottom of the Toolbox.

  3. Select the More Controls icon from the Toolbox. This displays a list of registered controls.

  4. If your control does not appear, it probably was not registered. To register it, select Tools, ActiveX Controls from the Microsoft Access main menu, which displays the ActiveX Controls dialog. Click the Register button, and select your control's path from the Add ActiveX Control dialog. Then click the Open button to register it.

  5. Select the control you want to add, and then click on the form where you want the control to appear.

To add a control to a Microsoft Word document or a Microsoft Excel spreadsheet, follow these steps:

  1. Open an existing document or spreadsheet, or use the one opened when you enter. To create a new document or spreadsheet, click File, New to open the New dialog. Click the OK button to use the defaults.

  2. If the Control Toolbox is not visible, select View, Toolbars, Control Toolbox from the main menu to display it.

  3. Select the More Controls icon from the Control Toolbox. This displays a list of registered controls (see fig. 15.12).

    FIG. 15.12
    Select the More Controls icon to display a list of registered controls.

  4. If you need to register your control, select the last item in the list, Register Custom Control, to display the Register Custom Control dialog. Select your control's path from the Register Custom Control dialog, and then click the Open button to register the control.

  5. Select the control you want to add. Microsoft Word places the control at the cursor position. To place the control on a Microsoft Excel spreadsheet, click on the spreadsheet where you want the control to appear.

Next you need to set the properties for the control. Make sure you are in Design Mode. Design Mode can be toggled using the View icon on the Form View toolbar in Microsoft Access (see fig. 15.13) and the Design Mode icon on the Control Toolbox in Microsoft Word and Microsoft Excel (see fig. 15.14). To set the control's properties, click with the right mouse on the control, and select Properties from the pop-up menu to display the Properties grid. Edit the properties as needed. You can click with the right mouse on the control and select xxxx Control Object, Properties to use the property pages to edit the properties; xxxx represents the control name.

FIG. 15.13
Toggle Design Mode in Microsoft Access using the View icon on the Form View Toolbar.

FIG. 15.14
Toggle Design Mode in Microsoft Word and Microsoft Excel using the Design Mode icon on the Control Toolbox.

To create code for events, make sure you are in Design mode. Right-click the control, and select Build Event in Microsoft Access, or View Code in Microsoft Word and Microsoft Excel to open the code window. The code window for Microsoft Excel is shown in Figure 15.15.

FIG. 15.15
The code window for Microsoft Word looks the same as the code window for Microsoft Excel.

You can now code as you would in a Visual Basic code window. To debug your code, press the F5 key or use the Debug menu.

You can also add an ActiveX control to a report the same way you add it to a form.

For more detailed information, refer to the Microsoft Office 97 Help files and Microsoft's Knowledge Base found on its Web site (http://www.microsoft.com/kb/).

If you compile the project, be sure to recompile if you change the code for your ActiveX control.

Tools for Testing Your Component

To ensure that your ActiveX control works correctly once in the user's hands, it needs to be thoroughly tested. Thorough testing involves completely testing every event, method, and property. The control must also be tested on every platform and, to the extent possible, with as many of the container applications used by your users as possible. This part of the chapter discusses using the OLE Control Test Container packaged with Microsoft Visual C++, your users, and automated testing tools to test your ActiveX control. You can also use the tools mentioned earlier in the chapter.

Visual C++ ActiveX Control Test Container

The ActiveX Control Test Container can be used to test the properties, methods, and events functionality of ActiveX controls. You can test the persistence of controls by saving properties to a stream or substorage, reloading properties, and viewing the stored stream data. The ActiveX Control Test Container can be integrated with the Visual C++ debugger, allowing you to step through the control's code.

After you compile and link your control, you can use the Test Container to change properties, invoke methods, and fire events to test the control. Select Tools, ActiveX Control Test Container from the Developer Studio menu to load the Test Container.

The first step is to insert your control into the ActiveX Control Test Container. Select Edit, Insert OLE Control. This displays the Insert OLE Control window (see fig. 15.16). Select your control from the Object Type list box, and then click the OK button to insert your control.

FIG. 15.16
The Insert OLE Control window displays all registered ActiveX controls in the
Object Type list box.

If your control is not in the list box, it probably was not registered. Click the Cancel button to close the Insert OLE Control window, and then use the following steps to register your control:

  1. Select File, Re_gister Controls to open the Controls Registry window.

  2. Click the Register button. Use the Register Controls window to locate your control.

  3. Select your control, and click the Open button to register the control.

  4. Click the Close button to close the Controls Registry window and return to the main window.

Now that the control is inserted, you can test the property, event, and method functionality of your control.

You can test changing a property through its property sheets or property dialog. To change a property via its property sheet, use the following steps:

  1. Click the control you inserted in the main window of Test Container to select the control.

  2. Select Edit, Properties... xxx Control Object, where xxx is the name of the control. This step displays the control's property page.

  3. Edit the value of the property.

  4. Click the Apply button to set the property to the new value.

  5. Click the OK button to close the control's property page.

To change a property via its property dialog follow these steps:

  1. Click the control you inserted in the main window of Test Container to select the control.
  2. Select View, Properties to show the Properties dialog for the control (see fig. 15.17).

    FIG. 15.17
    All of the control's properties may be changed using the Properties dialog.

  3. Select a property from the Property combo box. Edit the value in the Value text box.

  4. Click the Apply button to set the property to the value. If you enter a value that is the wrong data type, you will hear a beep, and the value will not be changed.

  5. Click the Close button to close the Properties dialog.

If you need to see when a property value changes, select View, Notification Log to open the Notification Log window. Whenever a property changes, a message will appear in this window (see fig. 15.18). If the property you are changing supports the OnRequestEdit notification, use the OnRequestEdit( ) Response radio buttons on the Notification Log dialog to see how your control reacts to the different responses from OnRequestEdit.

FIG. 15.18
Use the Test Container's Notification Log dialog to show the data-binding notifications when a property value changes.

To invoke a method, follow these steps:

  1. Click the control you inserted in the main window of Test Container to select the control.

  2. Select Edit, Invoke Methods to open the Invoke Control Method dialog.

  3. Select a method from the Name combo box at the top of the Invoke Control Method dialog (see fig. 15.19).

    FIG. 15.19
    Select a method from the top section of the Invoke Control Method dialog, set the para-meter values in the middle section, and view the method's return value in the bottom section.

  4. Enter the needed values in the parameter text boxes shown in the center of the Invoke Control Method dialog.

  5. Click the Invoke button to invoke the method. If there is a return value from the method, it will display at the bottom of the Invoke Control Method dialog.

  6. When you finish invoking methods, click the Close button to close the dialog.

To fire an event, perform an action that will cause the event to fire. For example, if you are testing the MFCControlWin control, you could invoke the CaptionMethod method to fire the Change event. To view which events are firing, select View, Event Log to display the Event Log dialog. When an event fires, the call to the event handler is displayed in the Event Log dialog (see fig. 15.20).

FIG. 15.20
When an event fires, the call to the event handler is displayed in the Event Log dialog.

To select which events are displayed, open the Events dialog for the control by selecting Edit, View Event List. An example of the dialog is shown in Figure 15.21. To toggle between showing and not showing an event, select the event and click the Log/No Log button. To log all events, click the Log All button. To not log any events, click the Log None button. Click the Close button when you are finished.

FIG. 15.21
If you want to display the events for the MFCControl, this is how the Events dialog will look.

The ActiveX Control Test Container provides a way for you to test the functions in your control. Select Edit, Embedded Object Functions to see a submenu of the functions. Select a function to execute, and that function will be executed. Table 15.1 lists the functions with a brief description.

Table 15.1 Embedded Object Functions
Action Description
Primary Verb Invokes control's primary verb.
Activate Activates control and puts it in Loaded state.
UI Activate Puts control in UI Active state.
Close Closes control and puts it in Loaded state.
Deactivate Deactivates control and puts it in the Loaded state.
Deactivate UI Only Restores OLE Control Test Container's original state.
Hide Hides control and puts it in Loaded state.
Open Puts control in stand-alone mode and Open state.
Reactivate and Undo Reactivates control and puts it in Loaded state.
Run Runs control and puts it in Loaded state.
Show Activates control and puts it in UI Active state.
Properties Shows property sheet for control.


The Test Container can run in two modes: Passive Container Mode or Simulated Design Mode. When Test Container is in Passive Container Mode, it does not automatically change the control's state. When it is in Simulated Design Mode, it does change the control's state automatically to mimic Design mode.

A powerful feature of the Visual C++ Debugger is the fact that you can integrate an executable. This means you can use OLE Control Test Container, or another container, to test your control and be able to step through the code. You could use the Visual Basic executable to test design mode and use a Visual Basic executable to test run mode. To set this up, use the following steps:

  1. Select Project, Settings from the Developer Studio menu to open the Project Settings dialog.

  2. If you have not compiled and linked in Debug mode recently, you should compile and link the debug version before continuing. The debug version must match the registered version for the debugger to work correctly.

  3. Make sure that Win32 Debug is selected in the Settings For combo box.

  4. Select the Debug tab (see fig. 15.22).

    FIG. 15.22
    Make sure Win32 Debug is selected in the Settings For list box, and then select the Debug tab.

  5. Enter the name of the executable you want to use with the debugger in the Executable for debug session text box. If you want to use the OLE Control Test Container, enter TSTCON32.EXE with the proper path. It can be found in the BIN directory of your Visual C++ directory. If you want to use the Visual Basic development environment, enter VB5.EXE with the proper path. You will find VB5.EXE in your Visual Basic directory.

  6. Click the OK button to save the settings, and exit the Project Settings dialog.

  7. Set any breakpoints you need to debug your control.

  8. Select Build, Start Debug, Go, or press F5 to start the debugger.

  9. A Microsoft Developer Studio dialog will appear, alerting you that there is no debug information for TSTCON32.EXE, or VB5.EXE if you're using Microsoft Visual Basic. It also asks you to press the OK button to continue. Click the OK button; you don't need to debug information for TSTCON.32EXE or VB5.EXE. If you want to prevent this dialog from appearing again, click the Do not _prompt in the future check box.

  10. Use the container as needed. The debugger will pause at the breakpoints after switching from the container application to the debugger. You can step through code, check values, and so on.

  11. When finished, exit the control application, or select Debug, Stop Debugging to exit the debugger.

Users

One of the best testing tools is your user community. If you correctly analyze the needs of your users before you even begin to create a control and use that knowledge during development, you will have a more marketable and widely used control. You also need to involve your user community in the testing of the control. Their feedback is needed not only to report bugs, but also to let you know how they like the look and feel. Feedback on the look and feel lets you know if you missed anything during the needs analysis and if your control will be popular.

When choosing users to be beta testers, include users with many different needs. For example, don't have all your beta testers use your control with only Visual C++. Select some who will be using your control with Visual C++, Visual Basic, the Internet, and so on. Make sure your group of beta testers will fully test the control's functionality. If you are developing controls for internal use, make sure the end users you select will use the system you are creating in a manner that fully tests your control.

Make sure that you stay in constant communication with your beta testers either through personal contact or through support personnel. Keeping in touch will let you know how they like the product. It will also let you know that the control is being well tested and that you are resolving all bugs. Make sure you fully explain the functionality of your control to the users. They can't test well if they don't understand what they are testing.

When users report a bug, ask them to explain exactly what they did to get the bug and what they did just before the bug occurred. This process may take a couple of phone calls or e-mails. The bug could be caused by something they did earlier; get as much information as possible. Next try to duplicate the problem. When duplicating the problem, try to create their environment--exactly. For example, if they are using Windows 95, try to duplicate the problem on Windows 95, not Windows NT. This applies to hardware as well. If they are using a machine that is slow and doesn't have much memory, don't try to re-create the problem on a souped-up development machine. We know this is difficult to do, but the closer you are to their environment, the quicker you will find the problem, and the better your chance of solving the real problem.

When you or your users find a bug, it is a good idea to try the control in different types of test containers to see how it behaves. Because different containers use ActiveX components in different ways, the problem may be in the way a container is using the control. For example, Microsoft Visual Basic uses an ActiveX control differently than the Visual C++ OLE Control Test Container. How a control behaves in different types of containers may also give you a better idea of what the problem is. The Microsoft OLE/COM Object Viewer tool (OLEView.exe) included with the Microsoft ActiveX SDK is also a good tool for debugging. It allows you to view the interfaces and components of an ActiveX control. Microsoft OLE/COM Object Viewer shows you what interfaces, constants, properties, and methods are contained in the registered copy of the ActiveX control. If the components of the control don't appear as you expect, maybe your ActiveX object didn't register correctly. Use The Microsoft OLE/COM Object Viewer to display the registry entries for the control.

The Microsoft OLE/COM Object Viewer is a good tool for checking the setup of your ActiveX objects. A copy of the Microsoft OLE/COM Object Viewer is available in the \Bin directory of the Microsoft ActiveX SDK directory or from Microsoft's Web page on the OLE/COM Object Viewer tool (http://www.microsoft.com/oledev/olecom/oleview.htm). Usually the Web site contains the most recent copy of the OLE/COM Object Viewer.

Automated Tools

Automated testing tools can also be used to test your control. These tools allow you to build scripts that store keystrokes to create unattended, consistent automated tests. The same script can be run across multiple machines, ensuring the same tests are run on different platforms. This helps to eliminate problems occurring on one platform and not another. If you add a new feature, you can add the needed tests to the script once and copy the script across all test machines. You don't have to manually retest on every platform, saving time and money.

One testing tool that supports testing ActiveX controls is the Rational Visual Test. (Rational recently acquired this product from Microsoft.) Rational plans on integrating Visual Test with its Rational Rose visual modeling tool. You can find information on testing ActiveX controls in the Microsoft Knowledge Base and in the Visual Test help files.

From Here...

This chapter has focused on using and testing your ActiveX component implementation. While the majority of the discussions revolved around ActiveX Controls, it is important to note that the same techniques can be applied to just about any component you develop. In addition to the tools we pointed out, more are appearing every day that incorporate ActiveX, including FrontPage and Visual InterDev and Microsoft BackOffice applications, such as Microsoft Transaction server and Microsoft SQL Server.

When creating, using, and distributing your component, you need to be as thorough as possible. Give the component to as many users as is feasible and test in as many containers as is practical.