ActiveX controls

ActiveX Fundamentals

ActiveX Control Fundamentals

Visual Basic 5 and 6 give you all the tools you need to create powerful ActiveX controls, which you can then reuse in all your projects. More precisely, you can create two different types of ActiveX controls:

  • Private ActiveX controls that can be included in any type of Visual Basic project. They're saved in files with the .ctl extension, and you can reuse them in any other Visual Basic project merely by adding the file to the project. (This is reuse at the source-code level.)

  • Public ActiveX controls that can be included only in ActiveX control projects; you have to compile them into OCX files, and then you can use them in any other Microsoft Windows application written in Visual Basic, Microsoft Visual C++, or any other development environment that supports ActiveX controls. (This is reuse at the binary level.)

Visual Basic 5 was the first language that permitted programmers to create ActiveX controls using a visual approach. As you'll see in a moment, you can create powerful controls by simply grouping simpler controls together: These controls are known as constituent controls. By putting together a PictureBox and two scroll bar controls, for example, you can create an ActiveX control that can scroll its contents. Visual Basic also allows you to create an ActiveX control without using any constituent controls. These are the so-called owner-drawn ActiveX controls.

You should also keep this in mind when working with ActiveX controls: You're used to distinguishing between two distinct types of people interacting with your program-the developer and the user. To better understand how ActiveX controls behave, you need to take another role into account, the author of the control itself. The author's job is to prepare a control that will be used by the developer to deliver an application to the user. As you'll see, the author's and developer's perspectives are sometimes different, even though the two roles might be occupied by the same person. (That is, you might act as the author of the control and then as the developer who uses it.)

Creating the UserControl Module

In this section, I'll show you how to create a sort of super-TextBox control that adds extra capabilities to the regular TextBox control, such as filtering out invalid characters. The steps that you have to take any time you create a new Public ActiveX control are the following ones:

  1. Add a new ActiveX control project to the environment. This new project already includes a UserControl module. (Alternatively, manually add a UserControl module from the Project menu if you're creating a Private ActiveX control.)

  2. Give the project a meaningful name and a description. The former becomes the name of the control's library, and the latter is the string that appears in the Components dialog box for all the projects that use this control. In this example, we'll use the project's name SuperTB and the description An enhanced TextBox control.

  3. Click on the UserControl designer's window to give it the focus, and then enter a value for the Name property of the control in the Properties window. In this example, you can enter SuperTextBox.

  4. Place one or more constituent controls on the surface of the UserControl designer. In this example, you need to add a Label control and a TextBox control, as shown in Figure 17-1.


Figure 17-1.
The SuperTextBox control at design time.

You can use any intrinsic control as a constituent control of an ActiveX control except the OLE Container control (whose Toolbox icon is disabled when an ActiveX control designer has the focus). You can also use external ActiveX controls as constituent controls, but if you use one you should ascertain that you have the legal right to encapsulate it in your own control. All the ActiveX controls in the Visual Basic package except DBGrid can be freely reused in your own ActiveX control. Always carefully read the license agreements for third-party controls before encapsulating any in your own controls. You'll find more advice about these matters in the "Licensing" section near the end of this chapter. Finally, you can create ActiveX controls that don't use constituent controls, such as the SuperLabel control that you can find on the companion CD in the same directory as the SuperText project.

Now you can close the UserControl designer's window and switch to the Standard EXE project that you are using as a test client program. You'll notice that a new icon is now active in the Toolbox. Select it, and drop an instance of your brand new control on the form, as shown in Figure 17-2.

Congratulations! You've just created your first ActiveX control.

I want to draw your attention to one specific point in the previous description. You need to explicitly close the ActiveX control designer window before using the control on the test container form. If you omit this step, the icon in the Toolbox stays inactive. In fact, Visual Basic activates the ActiveX control and prepares it for siting only when you close the designer window. Siting refers to the instant an ActiveX control is placed on its container's surface.

You need to keep in mind that you have to deal with two different instances of the control, the design-time instance and the run-time instance. Unlike other Visual Basic modules, a UserControl module must be active even when the test project is in design mode. This is necessary because the control must react to the programmer's actions, such as entering the value of a property in the Properties window or resizing the control on the parent form. When you're working with the ActiveX control designer open, however, the control itself is in design mode and therefore can't be used in a form. To run an ActiveX control, you need to close its designer window, as I explained earlier.


Figure 17-2.
An instance of the SuperTextBox control on a testform. The Properties window includes a number of properties that have been defined for you by Visual Basic.

Running the ActiveX Control Interface Wizard

Our first version of the SuperTextBox control doesn't do anything useful yet, but you can run the client application and ensure that everything is working and that no error is raised. To turn this first prototype into a useful control, you need to add properties and methods and write the code that correctly implements the new features.

To complete the SuperTextBox control, you need to add all the properties that the user of this control expects to find, such as ForeColor, Text, and SelStart. A few of these properties must appear in the Properties window; others are run time_only properties. You also need to add other properties and methods that expand the basic TextBox functionality-for example the FormatMask property (which affects how the control's contents is formatted) or the Copy method (which copies the control's contents to the Clipboard).

In most cases, these properties and methods map directly to properties and methods of constituent controls: for example, the ForeColor and the Text properties map directly to the Text1 constituent control's properties with the same names, whereas the Caption property corresponds to the Caption property of the Label1 constituent control. This is similar to the concept of inheritance by delegation that you saw in Chapter 7.

To facilitate the task of creating the public interface of an ActiveX control and writing all the delegation code, Visual Basic includes the ActiveX Control Interface Wizard. This add-in is installed with the Visual Basic package, but you might need to explicitly load it from within the Add-In Manager dialog box.

In the first step of the wizard, you select the interface members, as shown in Figure 17-3. The wizard lists the properties, methods, and events that are exposed by the constituent controls and lets you select which ones should be made available to the outside. In this case, accept all those that are already in the rightmost list except BackStyle, and then add the following items: Alignment, Caption, Change, hWnd, Locked, MaxLength, MouseIcon, MousePointer, PasswordChar, SelLength, SelStart, SelText, Text, plus all the OLExxxx properties, methods, and events. These members ensure that the SuperTextBox control matches nearly all the capabilities of a regular TextBox control. A few properties have been left out-namely, MultiLine and ScrollBars. The reason for these exclusions will be clear later.


Figure 17-3.
The first step of the ActiveX Control Interface Wizard. You can also highlight multiple items and add all of them in one operation.

Note

Unfortunately, the ActiveX Control Interface Wizard lets you include many properties, methods, and events that you should never add to the public interface of your controls-for example, the ToolTipText, CausesValidation, WhatsThisHelpID,and Validate event. As a matter of fact, Visual Basic automatically adds these members to any ActiveX control that you create, so you don't need to specify them unless you plan to use the control in environments other than Visual Basic. More on this later.

In the next step, you define all the custom properties, methods, and events that your ActiveX control exposes. You should add the FormatMask, FormattedText, CaptionFont, CaptionForeColor,and CaptionBackColor properties; the Copy, Clear, Cut, and Paste methods; and the SelChange event.

In the third step, you define how the public members of the ActiveX control are mapped to the members of its constituent controls. For example, the Alignment public property should be mapped to the Text1constituent control's Alignment property. The same holds true for the majority of the members in the list, and you can speed up mapping operations by selecting all of members and assigning them to the Text1control, as shown in Figure 17-4.


Figure 17-4.
In the third step in the ActiveX Control Interface Wizard, you canmap multiple members by highlighting them in the leftmost list and then selectinga constituent control in the Control combo box on the right.

A few members-for example, the Caption property-map to the Label1 constituent control. You must specify the name of the original member in the constituent control when the two names differ, as in the case of the CaptionForeColor, CaptionBackColor, and CaptionFont properties that correspond to the Label1's ForeColor, BackColor,and Font properties, respectively. At other times, you have to map a public member to the UserControl itself-for example, the Refresh method.

There might be members that can't be directly mapped to any constituent control, and in the fourth step of the wizard you define how such members behave. For example, you declare that the Copy, Cut, Clear, and Paste methods are Subs by setting their return type to Empty. Similarly, you specify that FormatMask is a String property that can be read and modified either at design time or run time, whereas the FormattedText isn't available at design time and is read-only at run time. You should also specify an empty string as the default value for these three properties because even if you change the property type to String, the Wizard doesn't automatically change the value 0 that it initially set as the default. You must enter the argument list for all methods and events, as well as a brief description for each member, as shown in Figure 17-5.

The otherwise excellent ActiveX Control Interface Wizard has some limitations, though. For example, you can neither define properties with arguments, nor can you enter a description for all the custom properties-the CaptionFont and CaptionForeColor properties in this case-that are mapped to constituent controls.

Caution

Beware, international programmers! Being written in Visual Basic, the ActiveX Control Interface Wizard inherits a curious bug from the language if the Regional Setting established in the Control Panel isn't English. When Boolean constants True and False are concatenated in a string, the value you obtain is the localized string corresponding to that value. (For example, in Italian you get the strings "Vero" and "Falso", respectively.) Thus, in these circumstances the Wizard doesn't produce correct Visual Basic code, and you might have to edit it manually to run it. Or, if you prefer, you can set the Regional Setting to English if you plan to run the Wizard often in a programming session.


Figure 17-5.
In the fourth step in the ActiveX Control Interface Wizard, you decide the syntax of methods and events and whether properties are read/write or read-only at run time.

You're finally ready to click on the Finish button and generate all the code for the SuperTextBox control. If you go back to the instance of the control on the test form, you'll notice that the control has been grayed. This happens each time you change the public interface of the control. You can make the ActiveX control active again by right-clicking on its parent form and selecting the Update UserControls menu command.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Debuggers don't remove bugs. They only show them in slow motion.”