Platinum Edition Using Visual Basic 5

Previous chapterNext chapterContents


- 24 -
Creating ActiveX Controls

ActiveX controls have gone through quite an evolution over the past few years; see how ActiveX controls have grown and changed from their earliest incarnation as Visual Basic controls.
There are two basic approaches to building ActiveX controls by using Visual Basic 5. Take a look at what each approach involves, and some of the issues you need to consider when choosing between the two approaches.
You build a simple ActiveX control, learning how to expose the control's properties, methods, and events.
Learn how you can take an existing control that almost does what you want and transform it into your own special creation.

One of the most exciting features of Visual Basic 5 is the ability to create your own ActiveX controls. No longer are you limited to using the controls created by C/C++ programmers; if you can dream up a great control, you can build it yourself by using Visual Basic. What's even better is that you are not limited to using the controls you create only in Visual Basic. You can use your controls in any application or development tool that can use ActiveX controls. This means that you can turn the tables and begin building ActiveX controls in Visual Basic that C++ programmers will be using in their applications. It's a brave new world for the Visual Basic developer.

This chapter discusses building your own controls by using the latest version of Visual Basic. It covers the various approaches that you can take and some of the issues that you need to take into consideration. The information contained in this chapter is then built upon in later sections, as you learn how to build your own ActiveX controls by enhancing an existing control that "almost" does what you need your control to do.

ActiveX Basics

ActiveX is a technology that was introduced by the Microsoft Corporation in March, 1996. It was not really a new technology, but a renaming of Microsoft's existing OLE technologies. These technologies include the OLE Controls that were introduced with Visual Basic 4 during the previous year. It was the OLE/ActiveX controls that introduced a way to build component objects that can be placed in various applications, including Web pages. This enhanced the ability of programmers to build robust applications quickly with prebuilt components.


NOTE: ActiveX isn't just a new name slapped on an old technology. Along with the new name, Microsoft significantly re-engineered its OLE technologies to make them more "network-friendly." In part, Microsoft removed from the OLE Control (OCX) specification most of the implementation requirements that had added unnecessary overhead to the controls by making them larger and slower than necessary. Along with these changes, Microsoft introduced several new technologies that were aimed specifically for use on the Web, including its Authenticode technology for signing controls and applications. In short, Microsoft put a lot of work into making the evolution of OLE into ActiveX a lot more than just a new name on an old technology.

ActiveX controls can be used in Web pages to add functionality and to greatly improve appearance. As HTML and scripting languages are fairly limited, ActiveX controls have no limitations. Web page designers can interact with the ActiveX controls on their pages with scripting languages such as VBScript.

ActiveX is the next step of the Visual Basic component technology. Visual Basic component technology was started with VBXs, which were used in 16-bit implementations, and were followed by OCXs, which were used in both 16- and 32-bit implementations.

With Visual Basic 5, you can create an ActiveX control as an ActiveX control project. These controls can be used with any container application that supports ActiveX controls. To use an ActiveX control on a Web page, the user's browser must support ActiveX. Microsoft Internet Explorer 3.0 and 4.0 support ActiveX controls. A typical ActiveX control as viewed by IE 3.0 is shown in Figure 24.1.

FIG. 24.1
The ActiveX control on this page allows users to select a specific html page based upon contents of the combobox.


NOTE: Netscape Communicator, the latest version of Netscape's popular Web browser, now supports ActiveX controls. Previous versions of Netscape's browser still require special plug-ins to accept ActiveX controls.

Building and Implementing an ActiveX Control: An Overview

The basic process of building an ActiveX control is simply a matter of following these steps:

1. Determine what you want your ActiveX control to do.

2. Determine what you want your ActiveX control to look like, if you want it to have any appearance at all.

3. Determine what properties, methods, and events your control will provide.

4. Determine whether you want to build your control by using the constituent (built-in) controls or by using other controls as building blocks for your control. When considering other controls, consider licensing and distribution issues.

5. Start a Visual Basic ActiveX control project and draw your control.

6. Add code to enable all the properties, methods, and events you want your control to have. Consider whether your control will still be safe for initialization and scripting with the enabling of properties and methods.

7. Create a storage location for your control and all of its supporting files. If you are using a project management system, such as Visual SourceSafe, register your project in it.

8. Build a test project and test your control. Make sure to use all the properties, methods, and events that you gave your control.

9. Compile your control into an OCX.

10. Use the Setup Wizard to build a distributable version, including all the supporting files.

11. If you plan on a Web-based control, test your control on an HTML form. Use the one the Setup Wizard made as a starting point. Test all properties, methods, and events from scripting code.

Two Ways to Build an ActiveX Control

Building a Visual Basic ActiveX control can be as easy or as difficult as you choose. It all depends on whether you can use existing controls in your design, how sophisticated your control's user interface will be, and of course, how much program code you have to write to implement the control's functionality. In any case, there are two basic ways to go about building a control:

These two methods of building a control are listed in the order of general difficulty, although, again, how difficult a control is to create depends on several other factors, as well.

This chapter looks at how to create ActiveX controls from existing controls. The next chapter, "Extending ActiveX Controls," explains how you can add additional functionality to your ActiveX controls.


NOTE: Before you begin building an ActiveX control, you need to decide what type of control it will be. Will your control perform all of its functions without using any nonconstituent controls? Does the control need another control? Will the control be a visual or nonvisual control? These decisions all have to be made before beginning your ActiveX control project.

Advantages of Using Constituent Controls

There are many advantages to assembling an ActiveX control from existing controls. The first is obvious: Because your control's user interface consists of existing controls, you don't have to draw the interface yourself. Another advantage is that your control's users will probably already be familiar with the controls that make up your new control. This familiarity makes your new control easier to use.

Still another advantage is that, when you add an existing control to your new custom control, you get the existing control's complete functionality, too; an important consideration when you consider how many event procedures, methods, and properties are supported by a standard control.

You can often use third-party controls as constituent controls, but usually you'll use Visual Basic's standard controls or intrinsic controls. The Visual Basic intrinsic controls are shown in Table 24.1.

Table 24.1 The Visual Basic Intrinsic Controls

Icon

Name Description

CheckBox A small button-like control that the user can check or uncheck.

ComboBox A control that is comprised of a scrollable list containing valid selections and an edit box into which the user can type selections. The user can also use the mouse to choose selections from the list.

CommandButton A typical push-button type of control.

Data A control that you can link to database fields.

DirListBox A control that displays the directories on the current drive.

DriveListBox A control that displays the drives on the system.

FileListBox A FileListBox displays the files in the current directory.

Frame A control that enables you to place controls into a group, by providing an outline to enclose the group and a caption to identify the group.

HScrollBar A control that represents a horizontal scroll bar.

Image A control that displays an image.

Label A control that holds a static (unchangeable) line of text.

Line A control that enables you to draw lines on a form or control.

ListBox A control that features a scrollable list from which the user can make a selection. Similar to a ComboBox, but without the edit box.

OptionButton A small, circular, button-like control that the user can use to toggle options on or off.

PictureBox A control that's similar to an Image control, but which features more methods.

Shape A control you can use to draw various types of shapes on a form or control.

TextBox A control that represents an editable line of text.

Timer A control that's used in Visual Basic projects to access and control Windows timers.

VScrollBar A control that represents a vertical scroll bar.

A big advantage of using the intrinsic controls as constituent controls is that you don't need to acquire additional licenses to distribute the controls with your programs. The intrinsic controls are built in to the Visual Basic runtime files that you always need to distribute. If you use third-party controls, you almost certainly have to pay licensing fees. (For more information on licensing, see Chapter 25, "Extending ActiveX Controls.")

Using Constituent Controls

The following sections take a look at how you can use constituent controls to build an entirely new control. The address control that you create can itself become a constituent control for future ActiveX controls; in this way, a complete library of controls can be built up quite rapidly and without a lot of coding.

Creating the Address Control

Now that you have some background information on using constituent controls, you can get started creating your first full-fledged ActiveX control. The control that you'll build in the following sections enables users to enter their name and address into a predefined form. To create the control, you'll use Visual Basic Label and TextBox controls as constituent controls. To build this control, follow these steps:

1. Start Visual Basic 5. If it is already running, choose File, New Project.

2. In the New Project dialog box, select ActiveX Control Project. A new project should start with a UserControl object named UserControl1, as shown in Figure 24.2.

FIG. 24.2
ActiveX controls can contain all of the controls that a regular application has.

3. Change the Name property of the UserControl to AddressPrj. If the Properties window is not visible, choose View, Properties Window or click the Properties Window button. Find the Name property and change it by typing Address.

4. Add five Labels to the form and give them the following properties:

Name
Caption
lblName
"Name:"
Name
Caption
lblStreet
"Street:"
Name
Caption
lblCity
"City:"
Name
Caption
lblState
"State:"
Name
Caption
lblZip
"Zip:"

5. Add five Text boxes to the form with the following properties.

Name txtName
Name txtStreet
Name txtCity
Name txtState
Name txtZip

6. Click the UserControl object and resize it so that the constituent controls fit neatly inside. You can resize the control by using the sizing handles or by changing the Height and Width properties in the Properties window to 3090 and 3810, respectively. The completed form will now look like that shown in Figure 24.3.

FIG. 24.3
The full set of constituent controls should look like this.

7. Save your project to its own folder, which you should name ..\Samples\Address. Save the UserControl with the name Address.ctl. Save the project with the name Address.vbp.

Adding Program Code to the Control

The next step is to add code that responds to the Resize event, which occurs whenever a control is created or resized.

To add program code for the Resize event, first double-click the UserControl object to display the control's code window. When the window pops up, it displays the UserControl_Initialize() event procedure. In the Procedures box, select Resize, and the UserControl_Resize() event procedure appears in the code window. Add the lines shown in Listing 24.1 to the UserControl_Resize() event procedure.

Listing 24.1 LSTz_01.TXT--Code for the UserControl_Resize() Event Procedure

    ` Don't let the developer make the
    ` height of the control too small.
    If UserControl.Height < 3090 _
        Then UserControl.Height = 3090
        
    ` Don't let the developer make the
    ` width of the control too small.
    If UserControl.Width < 1500 _
        Then UserControl.Width = 1500
        
    ` Change the width of the controls
    ` to fit into the resized UserControl.
    txtName.Width = ScaleWidth - 500
    txtStreet.Width = ScaleWidth - 500
    txtCity.Width = ScaleWidth - 500
    txtState.Width = ScaleWidth / 2 - 400
    txtZip.Width = ScaleWidth / 2 - 400
    
    ` Reposition the Zip Code controls.
    lblZip.Move ScaleWidth / 2 + 160
    txtZip.Move ScaleWidth / 2 + 160

After adding the previous lines to the UserControl_Resize() event procedure, be sure to save your changes by clicking the Save Project Group button on VB5's toolbar or by choosing File, Save Project Group.

Understanding UserControl_Resize()

When a developer (who uses the control to create an application or Web page) resizes the Address control, be sure that the control's interface still looks okay. For this reason, you don't want the height of the Address control to get smaller because then there won't be room for all the Label and TextBox constituent controls. (Okay, if you really want to, you can use smaller fonts, but who wants to go to all that trouble?) So, the first thing UserControl_Resize() does is make sure that the control's height doesn't get set to less than 3090:

If UserControl.Height < 3090 _
    Then UserControl.Height = 3090


NOTE: The height of 3090 is an arbitrary number. For the sake of this example, a height of 3090 was chosen. Your control height may be less than or greater than this size.

Now, if the developer tries to make the control too small, UserControl_Resize() will set the height back to where it belongs. The developer can make the control taller, but he can't make it shorter.


NOTE: Notice how you can change the value of a property with a line of code such as Object.Property = Value, where Object is the object whose property you want to change, Property is the name of the property to change, and Value is the value to which you set the property. Notice also that you separate the object and property names with a period.

Although you have to be careful about how the developer changes the control's height, the control's width has a little more flexibility. Because TextBox controls can scroll text, the TextBox doesn't necessarily have to be wide enough to hold the entire line that the user types in. So, your new control can allow the developer to change the width of the Address control. Still, you want to limit the width to a sensible amount. In Listing 24.1, that limit is 1500, which is enforced like this:

If UserControl.Width < 1500 _
    Then UserControl.Width = 1500


NOTE: As with the height, the width of 1500 is an arbitrary number. For the sake of this example. a width of 1500 was chosen. Your control width may be less than or greater than this size.

Because you can never know how the developer has set the Address control's size, you need to size and position the constituent controls every time a Resize event occurs. The first step in this task is to set the constituent controls' widths, like this:

txtName.Width = ScaleWidth - 500
txtStreet.Width = ScaleWidth - 500
txtCity.Width = ScaleWidth - 500
txtState.Width = ScaleWidth / 2 - 400
txtZip.Width = ScaleWidth / 2 - 400

ScaleWidth and ScaleHeight hold the width and height of the UserControl object's visible area. In the first three lines of the previous code segment, the code sets the width of the constituent controls to 500 twips less than the width of the UserControl object's visible width. The width of the txtState and txtZip controls is a little trickier to set because these controls are on the same line. To fit these TextBoxes properly, the code first divides ScaleWidth by 2, giving the total amount of space each TextBox can have. Then the code subtracts 400 twips to put a little space between the controls.

Because the controls for the State and Zip fields are on the same line, when the UserControl object changes width, the Zip controls (lblZip and txtZip) have to be repositioned. The UserControl_Resize() event procedure takes care of that little detail like this:

lblZip.Move ScaleWidth / 2 + 160
txtZip.Move ScaleWidth / 2 + 160


NOTE: You can use an object's Move() method to reposition the object. A call to Move() looks like object.Move left, top, width, height, where object is the object to move, left is the position of the object's left edge, top is the position of the top edge, width is the object's new width, and height is the new height. Only the left argument is required; that is, top, width, and height are optional arguments.

Testing the Address Control

You've created your control's interface and added code to handle one important event. You're now ready to see Address in action, by opening the test application's designer window and adding an instance of the Address control. At this point, you'll be playing the role of an application or Web page developer. In this role, you want to see how the control will act when another developer gets his hands on it.

After you have entered all the code for the control, you are ready to test the control. A good way to test your ActiveX control is in a control project. To test the Address control, follow these steps:

1. Remember to save your code.

2. Add a Standard EXE project to the project group.

3. Close the design and Code windows for the User Control. Notice an icon for your control appears in the Toolbox.

4. Add an instance of the Address control to Form1.

5. Set the properties of the control.

6. Run the test program and try out the control.

If you have problems with the control, you can use the same debugging techniques to find problems in controls that you used to find problems in standard programs. You can set break points and step through the code line by line, whether in the ActiveX Control project or in the Standard EXE project. (See Chapter 25, "Extending ActiveX Controls," for more information on debugging your code.)

As you can see, the Address control looks exactly as you designed it. That's because the first time the instance appears in the test application's form, it uses the width and height of the control as you set it when you designed the control. The sizes and positions of the constituent controls are handled in the UserControl_Resize() event procedure, based on the current size of the Address control.

To really see UserControl_Resize() in action, reduce the width of the Address control. When you do, the constituent controls automatically resize themselves according to the new Address size. If you try to reduce the height of the Address control, the control springs back to its minimum size. You can, however, enlarge the control as much as you like. If you reduce the width of the control as far as it'll go, you end up with something like Figure 24.4. No matter how narrow you try to make the control, it'll always stay at least at its minimum size.

Fig. 24.4
This is the test application when the Address control is at its minimum width.

Compiling the Address Control

After you've created and tested your control, you need to compile it into an .OCX file, which is the stand-alone binary version of the control that you can distribute. When you compile your control into an .OCX file, developers can install the control on their systems and then use the control in their own projects, regardless of whether they're working with a programming language, a Web-page authoring application, or some other development tool.

To create a stand-alone. OCX file for the Address control, perform the following steps:

1. Double-click Address in the Project Group window. The control's designer window appears.

2. Choose File, Make ADDRESS.OCX. The Make Project dialog box appears.

3. Change the control's file name to Address.ocx (you may also need to set the directory to where you want the file to be saved), and click OK. VB5 compiles the new control and writes the .OCX file out to your disk.

4. Choose File, Remove Project. When Visual Basic asks whether you want to remove the project, click Yes. (If you're asked to save files, also choose Yes.)

After completing the previous steps, your project group will contain only the test application, AddressTestApp. However, if you look at Visual Basic's Toolbox, you'll see that the Address control is again available. Now, however, Visual Basic will use the compiled control rather than the version that was originally part of your project group.


NOTE: If you need to, you can easily add the Address control project back to the control group from which you deleted it. Just select the File, Add Project command from VB5's menu bar, and then select the project from the Existing page of the Add Project property sheet.

The Address control is one of those controls that can easily be used as the basis for other ActiveX controls. One possible use for the Address control is to provide a consistent look and feel to all of your applications that require user data entry. Another possible use is in a Web page to collect data in a guest book control.

The Address control is by no means a complete and robust control. The next few sections examine how methods and events can be added to your control. Chapter 25, "Extending ActiveX Controls," provides some ways to make your control more robust and bulletproof.

See "Control Error Handling," Chapter 25

A Quick Example: Build the AXYesNo

In the previous example, you built an ActiveX control out of constituent controls. You added some code to one of the events and successfully tested the control in a test project. However, you did not add any additional methods or events. You used only those methods and events that were supported by your constituent controls. In the present example, you build an ActiveX control and provide some methods and events.

This ActiveX control has three constituent controls: two command buttons and one label. In this example, you toggle the caption of the label by clicking the two command buttons. To build this control, follow these steps:

1. Start Visual Basic 5. If it is already running, choose File, New Project.

2. In the New Project dialog box, select ActiveX Control Project. A new project should start with a UserControl object named UserControl1.

3. Change the Name property of the UserControl to AXYesNo. If the Properties window is not visible, choose View, Properties Window or click the Properties Window button. Find the Name property and change it by typing AXYesNo.

4. Add two command buttons to your UserControl. To add controls to the UserControl, click the CommandButton control in the Toolbox, and then draw the buttons, as in Figure 24.5.

FIG. 24.5
Draw two command buttons on the control drawing area by selecting the CommandButton icon and then clicking and dragging on the drawing area.

5. Position the two CommandButtons so that you can see both of them. To move a CommandButton, click and drag it across your UserControl. You can also resize it by dragging the sizing blocks located on each of its corners.

6. Name one of the command buttons cmdYes and the other cmdNo.

7. Set the caption of cmdYes to Yes and the caption of cmdNo to No.

8. Add a Label control to the UserControl object and name it lblDisplay.

9. Add code to the Click event of cmdYes to have lblDisplay's Caption property say Yes. To go to the Code window, click cmdYes twice or click the View Code button. The cursor should be set in the Private Sub cmdYes_Click() event. Add the code shown in Listing 24.2.

Listing 24.2 AXYESNO\AXYESNO.CTL--cmdYes Code

Private Sub cmdYes_Click()
    lblDisplay.Caption = "Yes"
End Sub
10. Add code to the Click event of the cmdNo button to have it change lblDisplay's Caption property to No. To navigate between object events inside of the code window, go to the object list and select the cmdNo object. Verify that the event you are looking at in the procedure list is the Click event. Add the code shown in Listing 24.3.

Listing 24.3 AXYESNO\AXYESNO.CTL--cmdNo Code

Private Sub cmdNo_Click()
    lblDisplay.Caption = "No"
End Sub
11. Choose Project, Project1 Properties to open the Project Properties dialog box, and then name the project AXEYesNo and provide a project description.

12. Build your control by selecting the File, Make AXYesNo.ocx menu entries.

13. Save your project to its own folder, which you should name ..\Samples\AXYesNo. Save the UserControl with the name AXYesNo.ctl. Save the project with the name AXYesNo.vbp.

14. Test the control in a test project. Choose File, Add Project. From the Add Project dialog box, select Standard EXE. Inside Visual Basic, close the UserControl object window. Notice that the user control object you made AXYesNo is now available in the Toolbox. Add a AXYesNo to Form1, as in Figure 24.6. Now, test your control by choosing Run, Start, or by clicking the Start button. Click each of the command buttons and verify that they work correctly, as in Figure 24.7. Stop the project by choosing Run, End, or by clicking the End button.

FIG. 24.6
Once you close the window containing the control you are developing, it becomes available in the Toolbox for use in any other Visual Basic application.

15. Test your ActiveX control from an HTML container by using the Setup Wizard. Close Visual Basic. From the Visual Basic program group on the Start menu, select Application Setup Wizard. On the Select Project dialog box, select ...\AXYesNo\AXYesNo.vbp and check Create Internet Download Setup, as in Figure 24.8.

FIG. 24.7
When you run the standard Visual Basic project, you can verify that your control works correctly.

FIG. 24.8
To build the necessary files for use in an HTML document, you need to use the Application Setup Wizard to create an Internet Download Setup.

16. On the Internet Distribution Location dialog box, pick a location where you want your distribution files to become available.

17. On the Internet Package dialog box, pick Use Alternate Location for runtime components, but do not give a location, as in Figure 24.9. A blank location will put the files with the other runtime files.

FIG. 24.9
You can specify whether the Visual Basic runtime files (and other necessary files) will be downloaded from the Microsoft Web site, the same Web site as your control, or a third Web site.

18. On the Internet Package dialog box, click the Safety button. On the Safety dialog box, specify that your control is Safe for Initialization and Safe for Scripting (these settings will be discussed in greater detail in Chapter 25, "Extending ActiveX Controls"), as in Figure 24.10.

FIG. 24.10
By marking your control as safe for initialization and scripting, you place your guarantee that your control can't harm the user's computer, even if used in HTML documents that you didn't build.

19. Move forward through the ActiveX Server Components dialog box. In the File Summary dialog box, the Setup Wizard shows you a summary of the files that will be included in the package, as in Figure 24.11.

FIG. 24.11
The File Summary dialog box shows which files will be included in the Internet download files that will be packaged for inclusion on a Web site.

20. After the Setup Wizard has completed building the Internet Download files, open the AXYesNo.HTM document in Internet Explorer to test your control in a Web browser, as in Figure 24.12.

Exposing Properties, Methods, and Events

You can make properties, methods, and events of your ActiveX controls available to Web designers to increase your controls' flexibility. After properties, methods, and events are exposed, they are available to be manipulated from script code on an HTML page, such as VBScript. You can make the native properties, methods, and events of your constituent controls available, or you can make up your own properties, methods, and events for the special functionality that you are trying to achieve with your control. You need to be careful in what you enable, as it might make your control unsafe.

See "Marking Your Controls Safe for Scripting and Initialization," Chapter 25

FIG. 24.12
After the Setup Wizard has completed building the download files, it creates a simple HTML file you can open in Internet Explorer to test your control.

Exposing Properties of ActiveX Controls

Properties are characteristics of your controls. By changing properties, you can change the appearance and behavior of ActiveX controls. By exposing your ActiveX control's properties, you allow Web developers to manipulate your control. The availability of your ActiveX control's properties is controlled by property procedures. A property procedure is a public procedure that makes your property available to the outside world. Property procedures allow you to make properties read, write, or read and write.

You need to implement two property procedures for all properties that you want to make available to the user of your control. These two property procedures are the Get and Let procedures. The property Get procedure allows the current value of the property to be read by programming code or script, whereas the property Let procedure allows the current value of the property to be changed by the code. These methods also allow the property to appear in the Properties window when using the control in a Visual Basic application.

In the following example, you make the UserControl object that you made in the first example have a public property named BackColor, which will be available for read and write. To make a property of your control available to be read from script, make a property Get procedure. The name of the procedure is BackColor, and it is of type OLE_Color. It returns the value of the UserControl, as seen in Listing 24.4.

Listing 24.4 AXYESNO\AXYESNO.CTL--Reading the BackColor Property

Public Property Get BackColor() As OLE_COLOR
    BackColor = UserControl.BackColor
End Property

To make a property available to be changed from script, use a property Let statement, as in Listing 24.5.

Listing 24.5 AXYESNO\AXYESNO.CTL--Setting the BackColor Property

Public Property Let BackColor(ByVal New_BackColor As OLE_COLOR)
    UserControl.BackColor() = New_BackColor
    PropertyChanged "BackColor"
End Property

To the Web designer, your ActiveX control should look like one object, although it might be made of many constituent controls. For that reason, a Web designer should have to change only one property to change one attribute--for example, there should be only one BackColor property. You can change multiple objects on your control's properties with one property procedure. For example, if you want the BackColor of the UserControl and the label to have the same BackColor, use one property procedure and have it modify two properties, as in Listing 24.6. This enables you to change both BackColor properties with the single property.

Listing 24.6 AXYESNO\AXYESNO.CTL--Setting the BackColor Property of Both the UserControl and the Label

Public Property Let BackColor(ByVal New_BackColor As OLE_COLOR)
    UserControl.BackColor() = New_BackColor
    lblDisplay.BackColor() = New_BackColor
    PropertyChanged "BackColor"
End Property

Exposing Methods of ActiveX Controls

Methods give Web designers the ability to perform actions on the objects of their ActiveX controls. A method is just a function or sub that is declared as public. The function or sub's name associates with the name of a method of an object. For instance, you can use the code in Listing 24.7 to add a method to the AXYesNo control, which can then be used to set the label.

Listing 24.7 AXYESNO\AXYESNO.CTL--SetText Method

Public Sub SetText(Item As String)
 lblDisplay.Caption = Item
End Sub

Exposing Events of ActiveX Controls

By exposing events, you give Web designers the ability to call the code that is associated with those events.

To expose an event, you first declare the event's name in the General Declarations section of your UserControl object. Use the keyword Event and then the events name, followed by parentheses--for example, Event Click() declares there will be a Click event.

Second, create a procedure that uses your new event by using the code in Listing 24.8.

Listing 24.8 AXYESNO\AXYESNO.CTL--Exposing the cmdNo's Click Event

Private Sub cmdNo_Click()
    `Change the caption
    lblDisplay.Caption = "No"
    `Raise the Click event
    RaiseEvent Click
End Sub

Enhancing ActiveX Controls

The previous sections introduced the concepts involved in creating ActiveX controls, including how to place controls on a User Control Window, and how to create an entirely new control by adding properties, methods, and events. However, you can also create "new" controls simply by adding capabilities to an existing control. This means you will be working with a single base control, but adding properties, methods, and events to provide additional capabilities to the user. For example, you might want a text box that accepts only certain characters, or perhaps a scroll bar that works with a range of letters rather than numbers. Placing the code that performs these tasks into an ActiveX control makes it easier to use the code in future programs. For example, rather than adding special code to every TextBox control in your program, you simply use your "enhanced" control in place of the text box.

To create these enhanced controls, you use many of the same techniques that you have already learned. However, you also can use a Visual Basic Wizard to make quicker work out of the process, which is explained later in the chapter.

Adding Capabilities to a Control

To create an enhanced control, follow these five basic steps:

1. Start a new ActiveX control project.

2. Add the base control to the User Control Window.

3. Add the properties and methods to the control.

4. Test the control in a test application.

5. Compile your control so that others can use it.

The following sections walk you through these steps, using a text box as the base control. Your "enhanced" text box will have a property that allows the programmer to choose a set of acceptable characters that the user can enter. This control will be called TxtCharLimit (short for "Limited Character TextBox"). It will be just like the standard TextBox but with one additional property, CharAccept, which will allow the user to choose either all characters, just letters, or just numbers.

Creating the Basic Control

The steps to create the enhanced text control are very similar to the steps you used to create the Address and AXYesNo controls. For the enhanced text control, these steps are as follows:

1. Start a new ActiveX control project.

2. Add a text box to the User Control Window with the upper-left corner of the text box in position 0, 0.

3. Name the text box txtCharSet and clear its Text property

4. Set the properties of the ActiveX project and the User Control to the values specified in Table 24.2.

To set the first three values in the table, use the projectname Properties dialog box. To set the remaining values, highlight the UserControl object and press F4 to show the Properties window.

Table 24.2 Project and Property Settings for the Enhanced Text Custom Control

Item Setting
Project Type ActiveX Control
Project Name TextLimited
Project Description Text Box for Limited Character Set
User control Name property TxtCharLimit
User control Public property True

When you have completed setting up the user interface of the enhanced text control, it should look like the one in Figure 24.13.

You also need to set up the Resize event procedure of the User Control to make the text box fit the space that is drawn by the developer when using your control. This Resize event procedure is shown in Listing 24.9.

FIG. 24.13
A simple text control can be enhanced with other capabilities.

Listing 24.9 TXTCHARLIMIT.CTL--Using the Resize Event to Make Sure the Text Control Fills the Space

Private Sub UserControl_Resize()
  txtCharSet.Height = UserControl.ScaleHeight
  txtCharSet.Width = UserControl.ScaleWidth
End Sub

The simple two-line Resize event procedure is all the code necessary for the user interface of your sample control. Its purpose is to keep the text box the same size as the UserControl object. Before moving on, test it by performing the following steps:

1. Save your project.

2. Close the UserControl window. If you have the Toolbox open, you will notice a new icon appear for your control.

3. Choose File, Add Project. Add a Standard EXE project.

4. Draw your control on Form1 and try resizing it.

The purpose of jumping the gun like that is to get you used to the idea that the code in your ActiveX control does not have to be explicitly executed. Remember, when developing an ActiveX control, the code you write is used at design time in the host program.

For now, remove the Standard EXE project by right-clicking it in the Project Explorer Window and then choosing Remove Project1. Now it is time to work on the enhancements to the control.

Creating the Additional Capabilities

The enhancement you are going to make to the TextBox control is to tell it whether it should accept any characters, just letters, or just numbers. You accomplish this by adding your own property, called CharAccept, which can have one of the following three values:

The first thing you need is a private variable to store the property value internally. To do this, create the variable in the General Declarations section of the UserControl object:

Private mCharAccept As Integer

Next, you need to create the new property, called CharAccept. You can do this either by typing in the Let and Get procedures by hand, or by choosing Tools, Add Procedure, Property. The code for the CharAccept property is fairly easy to understand. When the developer needs the value of the CharAccept property, the Property Get procedure simply passes what is stored in the private variable. When the value of the CharAccept property is set, the Property Let procedure assigns one of the valid values to the private variable. The following is the code for both Property procedures:

Public Property Get CharAccept() As Integer
     CharAccept = mCharAccept
End Property
Public Property Let CharAccept(ByVal nNewValue As Integer)
       
       Select Case nNewValue
        Case 1 To 2
            mCharAccept = nNewValue
        Case Else
            mCharAccept = 0
       End Select
       
       PropertyChanged "CharAccept"
       
End Property

Notice the use of the PropertyChanged method. This method works with the ReadProperties and WriteProperties events, which you see in the next few paragraphs.

You now need to use the InitProperties event of the user control to specify an initial value of the property, as follows:

Private Sub UserControl_InitProperties()
   mCharAccept = 0
End Sub

This code makes sure that a value is set, even if the developer does not set it.

You also need to create the code for the WriteProperties and ReadProperties events to preserve the design time settings of CharAccept. These two events use the PropertyBag object to save and retrieve the value of the CharAccept property. The PropertyBag object enables you to maintain the design environment value of CharAccept. The code for these two events, shown in Listing 24.10, is not hard to understand. What is important, however, is why you need the code.

Listing 24.10 TXTCHARLIMIT.CTL--Holding the Property Value

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
   mCharAccept = PropBag.ReadProperty("CharAccept", 0)
End Sub
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
   PropBag.WriteProperty "CharAccept", mCharAccept, 0
End Sub

Remember that an ActiveX control's code starts executing the moment you draw it on a form. Suppose you set the value of a property during design time. In your sample control, assume you set the value of CharAccept to 1. You also may change it several times while your program is running. The normal behavior for a control is to revert to its original design-time values when the program ends, thus adding the requirement of maintaining two separate states of the property.

More simply put, if you change a property at design time, the control has to know to get this new value rather than use the default. Conversely, if the property's value is changed during program execution, the control has to retrieve the value when it returns to the design state.

The PropertyBag object allows your ActiveX control to store properties about itself, making this behavior possible. The PropertyChanged method provides notification that the user has changed a property. By knowing the state of the program and whether the PropertyChange method has been invoked, VB can fire the WriteProperties and ReadProperties events.

The next step in your sample project is to create the code that makes it do something different than a normal text box. In this case, you use the text box's KeyPress event to scan each character as it is entered. Visual Basic will pass the ASCII code of the characters through the event's KeyAscii parameter. Depending on the ASCII code and setting of CharAccept property, you will either accept the character or set KeyAscii to 0, which causes the text box to not display the character.

In addition to not displaying the character, you want to inform the host program that the user has entered an invalid character. You do this by creating an event called UserError. To create this event, add the following line of code to the General Declarations section of the UserControl object:

Public Event UserError()

This event works like an event in any other control; someone using your control can place code in it. The only thing you have to do is fire the event by using the RaiseEvent method.

Because there are three sets of acceptable characters, you can use a Select statement to handle the choices. One other item of note--you need to enable the backspace key (ASCII code 8) in any of the character sets that you use. Otherwise, the user won't be able to delete the previous character. The code for the KeyPress event is shown in Listing 24.11.

Listing 24.11 TXTCHARLIMIT.CTL--Using the KeyPress Event to Handle Screening the Keys Entered by the User

Private Sub txtCharSet_KeyPress(KeyAscii As Integer)
    If KeyAscii = 8 Then Exit Sub
    
    Select Case mCharAccept
        Case 0 `Any character is acceptable
            Exit Sub
        Case 1 `Only numbers may be entered
            If KeyAscii >= 48 And KeyAscii <= 57 Then
                Exit Sub
            Else
                KeyAscii = 0
                Beep
                RaiseEvent UserError
            End If
        Case 2 `Only letters may be entered
            If KeyAscii >= 65 And KeyAscii <= 90 Then
                Exit Sub
            ElseIf KeyAscii >= 97 And KeyAscii <= 122 Then
                Exit Sub
            Else
                KeyAscii = 0
                Beep
                RaiseEvent UserError
            End If
    End Select
End Sub

The code in this listing is fairly simple. KeyAscii represents the typed character, which is checked for validity by Select Case and If statements. If the character falls outside an acceptable range, the control beeps and raises the UserError event.

Testing the Capabilities

After you have entered all of the code for the control, you are ready to test the control. To test the TxtCharLimit control, follow these steps:

1. Remember to save your code.

2. Add a Standard EXE project to the project group.

3. Close the design and Code windows for the User Control.

Notice that an icon for your control appears in the Toolbox.

4. Add an instance of the TxtCharLimit control to the form in the test application.

5. Set the properties of the control.

6. Run the test program and try out the control. Try setting the CharAccept property to different values to verify that it accepts only the keystrokes you want.

If you have problems with the control, you can use the same debugging techniques to find problems in a control as you do for finding problems in standard programs. You can set break points and step through the code line by line, whether in the ActiveX Control project or in the Standard EXE project. (See Chapter 8, "Programming Visual Basic," for more information on debugging your code.)

Choosing a Toolbox Icon

One thing you may have noticed by now is that all the custom controls you create have the same symbol in the Toolbox. This can cause a lot of confusion if you are working with multiple controls. Although the ToolTips provide a description of the control, it is better to have a custom icon to identify each control. You can do this by setting the value of the ToolboxBitmap property of the user control. This property determines what is displayed in the Toolbox for your control. If the property is set to None, the default icon is used. You can set the property to any bitmap, but be aware that the Toolbox icon is only 16 x 15 pixels. Therefore, you should use custom bitmaps that are created in that size.

Using the ActiveX Control Interface Wizard

When you created the CharAccept property of the enhanced text box, you created one piece of the public interface of the control. However, your users probably will also want to be able to access most of the standard properties, methods, and events of the text box. For example, you may have noticed that the Text property was not accessible from your custom control. This makes sense because you did not add any code for it. The section "Exposing Properties of ActiveX Controls" exposed properties with the same name as the component property to allow the user to access these properties. Because there were only a few properties, each property was created by hand. However, you can imagine that handling this for the dozens of properties of a control could get very tedious.

Fortunately, Visual Basic provides a tool to make this process much easier--the ActiveX Control Interface Wizard. First you tell the Wizard the names of all the properties that you want to have for your control. It then enables you to "bind" the properties of your control to the properties of a component of your control. The end result is that the Wizard generates the appropriate code for you.

Adding the Wizard to Visual Basic

The first step to using the VB ActiveX Control Interface Wizard is adding it to your design environment. For this purpose, Visual Basic includes the Add-In Manager. To start the Add-In Manager, choose Add-Ins, Add-In Manager. This opens the Add-In Manager dialog box

To add the VB ActiveX Control Interface Wizard, click the box next to the name of the Wizard. This places a check mark in the box, indicating that the Wizard will be part of your desktop. Next, click the OK button to exit the Add-In Manager and add the Wizard to Visual Basic.

Next, you need to re-create the Limited text control by using the Wizard. To begin, start a new ActiveX Control project and draw a text box on the UserControl window. Set up the names and sizes the same way you did in the previous example. Next, start the Wizard by choosing the ActiveX Control Interface Wizard item from the Add-Ins menu. The Wizard will start by displaying the initial screen, shown in Figure 24.14. You then click the Next button to start the actual work of setting up your properties.

FIG. 24.14
The ActiveX Control Interface Wizard simplifies the process of creating properties by creating much of the code for you.


NOTE: For the Wizard to work most effectively, you must add all the required components to the user control before starting the Wizard.

Selecting and Creating Properties

The next step in using the Wizard is to select the properties, methods, and events that you want to make available to your control. Collectively, properties, methods, and events are referred to as members. On page two, shown in Figure 24.15, the Wizard contains a list of the names of just about every item that you could find in any control in Visual Basic. To select a property or method to create, highlight the name of the item in the Available names list, and then click the right arrow button to select the item. For your sample control, highlight the Text property on the left and click the right arrow button.

FIG. 24.15
Select properties, methods, and events for your control from the Available names list.


TIP: You can also select an item by double-clicking it in the list.

After you add the Text property to the Selected Names list, click the Next button to move to the next page of the Wizard.


NOTE: You may have noticed that the selection of properties works just like the two-column pick list control that was created in Chapter 9, "Using the Windows Standard Controls."

After selecting the predefined properties, methods, and events for your control, you are taken to the page of the Wizard where you can enter the new custom items for your control. The Create Custom Interface Members page of the Wizard contains a list of all the custom members that will be created for your control.

If you have previously defined public properties or other members, they will appear in this list when you first access the page. From this page of the Wizard, you can add new members, or edit or delete existing ones. To add a new member, click the New button of the Wizard. This opens the Add Custom Member dialog box. In this dialog box, specify the name of the member and its type. Create the CharAccept property by typing CharAccept in the Name field, and then clicking OK.

While you are on this step, create the UserError event. Then click the Next button to move on.


CAUTION: It is advisable not to edit members of the control that you previously defined with code alone. This is because the Wizard works by analyzing comments it places in the code. The Wizard may or may not be able to correctly interpret your hand-typed code.

Assigning Properties

The next step in the Wizard is to assign the public members of the custom control to members of the constituent controls. This process is referred to as mapping the members. For example, rather than creating your own Text property, you can simply map the Text property of your custom control to the Text property of txtCharSet. The Set Mapping page of the Wizard, shown in Figure 24.16, contains a list of all the properties, methods, and events that you identified as being part of the public interface of the custom control.

FIG. 24.16
Mapping the public members of the control gives you a direct link to items in the constituent controls.

The Set Mapping page contains two combo boxes for identifying the control and the control's member to which a public member should be mapped. To map a single public member of the custom control, first select the member in the Public Name list. Go ahead and highlight the Text property on the left. Next, select txtCharSet from the Control drop-down list. (This list contains the names of all the components in your custom control.) After selecting the component, you can select the member of the component from the Member drop-down list. In this case, the Text property will be selected automatically for you. This process is illustrated in Figure 24.17 for the Text property of the TxtCharLimit control.

FIG. 24.17
Select all the public members for the TxtCharLimit control and let the mapping occur automatically.

Note that with this screen, you can map more than one public member at a time. The list of public names supports multiple selections. You can select multiple members from the list, then select a component to which to map the members. Each public member will be mapped to the property or method of the component that bears the same name. For example, the Text property of the custom control would automatically map to the Text property of a text or combo box.

After you have mapped the Text property, click the Next button to proceed to the final page of the Wizard. This final page, shown in Figure 24.18, lets you set the attributes of each public member that is not mapped to a constituent control.

Depending on the type of member you are creating, the Wizard allows you to specify different attributes. For a property, you can specify the type of data the property will hold, the default value of the property, and what type of access the user has to the property at design time and run time. The access type determines if a Property Let, Property Get, or both procedures are created for the property. For Run Time access, you can choose Read/Write, Read Only, Write Only, or none. For Design Time access, you can choose Read/Write, Read Only, or none.

For your sample control, set the Data Type of the CharAccept property to Integer and set the default value to 0. You can also type an optional description in the Description box. Property descriptions appear at the bottom of the Properties window during design time. Because this is the final step of the Wizard, you now are ready to click the Finish button.

FIG. 24.18
Set the attributes for properties and methods before completing the code for the control.

Finishing the Code

After you click the Finish button, the ActiveX Control Interface Wizard creates a number of code modules in your control. The Wizard also displays a summary page, providing you with details of the steps remaining to finish your control.

After reviewing the information on the summary page, you can take a look at the code that was generated by the Wizard. You can view the code by clicking the user control in the Project window and then clicking the View Code button. This opens the Code window containing the code that the Wizard created for you.

Take a look at some of the pieces of the code that is generated. First, in the General Declarations section, you will find that the Wizard has created constants for the default values of any unmapped properties. The CharAccept property has been given a default value of 0. In addition, the Wizard has automatically created the private property variable CharAccept. This is followed by the declaration of any events that you requested to be included in the control. A sample of this code is shown in Listing 24.12. If you mapped any events, you will notice that the Wizard places comments in the code that indicate how events are mapped to component events.

Listing 24.12 TEXTLIMITED.CTL--Declarations Code Generated by the Wizard

Option Explicit
`Default Property Values:
Const m_def_BackColor = 0
Const m_def_ForeColor = 0
Const m_def_CharAccept = 0
`Property Variables:
Dim m_BackColor As Long
Dim m_ForeColor As Long
Dim m_CharAccept As Integer
`Event Declarations:
Event Click() `MappingInfo=txtCharset,txtCharset,-1,Click
Event DblClick()
Event UserError()
Event KeyPress(KeyAscii As Integer)

The declarations of variables and events are followed by the property procedures. These procedures are created for properties that are mapped to a component property and those that are custom properties. As seen in Listing 24.13, the code for the Text property is complete, whereas the CharAccept property has a skeleton function ready for you to finish.

Listing 24.13 TEXTLIMITED.CTL--Property Procedures Provide the Means to Set and Retrieve Property Values

`WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES!
`MappingInfo=txtCharset,txtCharset,-1,Text
Public Property Get Text() As String
    Text = txtCharset.Text
End Property
Public Property Let Text(ByVal New_Text As String)
    txtCharset.Text() = New_Text
    PropertyChanged "Text"
End Property
Public Property Get CharAccept() As Integer
    CharAccept = m_CharAccept
End Property
Public Property Let CharAccept(ByVal New_CharAccept As Integer)
    m_CharAccept = New_CharAccept
    PropertyChanged "CharAccept"
End Property

Note that if you had requested any methods, the Wizard would create them as Functions, instead of Sub procedures.

Finally, the code to read and write property values to the PropertyBag object is generated automatically. This code is illustrated in Listing 24.14.

Listing 24.14 TEXTLIMITED.CTL--UserControl Events Set Up the Control as Changes Are Made and Saved

`Load property values from storage
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    m_BackColor = PropBag.ReadProperty("BackColor", m_def_BackColor)
    m_ForeColor = PropBag.ReadProperty("ForeColor", m_def_ForeColor)
    txtCharset.Text = PropBag.ReadProperty("Text", "")
    m_CharAccept = PropBag.ReadProperty("CharAccept", m_def_CharAccept)
End Sub
`Write property values to storage
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    Call PropBag.WriteProperty("BackColor", m_BackColor, m_def_BackColor)
    Call PropBag.WriteProperty("ForeColor", m_ForeColor, m_def_ForeColor)
    Call PropBag.WriteProperty("Text", txtCharset.Text, "")
    Call PropBag.WriteProperty("CharAccept", m_CharAccept, m_def_CharAccept)
End Sub

To complete the coding of your control, you need to add the custom code that is required for the CharAccept property and KeyPress event because the Wizard created only a skeleton for these items. After all, if the Wizard could do everything, then you would be out of a job!

Using the Property Pages Wizard

You have seen Property Pages used for some of the controls that come with Visual Basic. These dialog boxes make it easy for you to set the properties of a control by organizing them into groups. You can create property pages for your own custom controls by using the Property Pages Wizard. Like the ActiveX Control Interface Wizard, you have to add the Property Pages Wizard to the desktop by using the Add-In Manager. After this is done, you can access the Wizard from the Add-Ins menu of Visual Basic. As you start the Property Pages Wizard, you are shown an introductory screen that explains the purpose of the Wizard. Clicking the Next button on this page takes you to the first page, where the real work is done.

Creating the Pages

The first page of the Wizard lets you define the pages of the Property Pages dialog box (see Figure 24.19). If you have included Font and Color properties in your control, the Wizard starts out with two default pages--StandardColor and StandardFont. If you do not need these pages, just click the box next to the name to remove them from your Property Pages.

In addition to the default pages, you can add new pages to the dialog box. Clicking the Add button brings up the Property Page Name dialog box, which is an input box where you can enter the name of the page to create. As you add a page name, it is placed in the list of available pages and is automatically checked. The order of the page names in the list is the order in which the tabs will appear in your Property Pages dialog box. You can change the order by selecting a page and using the arrow keys to move it within the list.

FIG. 24.19
Create new pages or rename old ones in the Property Pages Wizard.

When you have finished adding pages to the dialog box, click the Next button to move to the next page of the Wizard.

Adding Properties to the Pages

The next step in creating your Property Pages is to add the appropriate properties to each page of the dialog box. The Add Properties page of the Property Pages Wizard is shown in Figure 24.20.

FIG. 24.20
The Add Properties page displays a list of available properties and shows the defined pages of the dialog box.

To add a property to a page, click the tab corresponding to the page where you want the property placed, and then select the property from the Available Properties list and click the right arrow button. Notice in Figure 24.20 the addition of a General property page and the inclusion of the CharAccept property. In addition, if you have the default pages of StandardColor and StandardFont, you will notice that the appropriate properties have already been added to these pages.


TIP: You can drag and drop a property onto a tab to place it on the corresponding page of the Property Pages.

When you have finished adding properties to the pages, click the Finish button to complete the creation of your Property Pages. As with the ActiveX Control Interface Wizard, the Property Pages Wizard shows you a summary page that provides additional information to complete your custom control.

Using the Property Pages in Your Applications

To use the Property Pages you created, you need to add an instance of your custom control to a project. Then, in the Properties window, click the ellipsis button next to the Custom property. Then, just like the Property Pages of other controls, your Property Pages dialog box appears to allow the user to customize the control. A sample of a custom control's Property Pages is shown in Figure 24.21.

FIG. 24.21
Your Property Pages help users set up your custom control.


TIP: You can also access the Property Pages by right-clicking the control and then selecting the Properties item from the context menu.

Creating Other Enhanced Controls

Now that you have seen the general concepts for enhancing controls, you are ready to begin creating your own enhanced controls. One idea to get you started is a scroll bar that lets you select letters rather than numbers. This scroll bar lets the user set the upper and lower range of letters for the bar, and to set whether the letters returned by the Value property are uppercase or lowercase. Figure 24.22 shows the use of the scroll bar in a program, and Listing 24.15 shows the code required to make the scroll bar work.

FIG. 24.22
Use a scroll bar to enter letters.

Listing 24.15 LTRSCROLL.CTL--Code to Make the LtrScroll Control Work

`Default Property Values:
Const m_def_Max = 26
Const m_def_Min = 1
Const m_def_Value = 0
Const m_def_ReturnCase = 0
`Property Variables:
Dim m_Max As Integer
Dim m_Min As Integer
Dim m_Value As Integer
Dim m_ReturnCase As Integer
Private Sub hsbLetter_Change()
    RaiseEvent Change
End Sub
Public Property Get Max() As String
    m_Max = hsbLetter.Max
    Max = Chr(m_Max + 64)
End Property
Public Property Let Max(ByVal New_Max As String)
    m_Max = Asc(UCase(New_Max)) - 64
    hsbLetter.Max = m_Max
    PropertyChanged "Max"
End Property
Public Property Get Min() As String
    m_Min = hsbLetter.Min
    Min = Chr(m_Min + 64)
End Property
Public Property Let Min(ByVal New_Min As String)
    m_Min = Asc(UCase(New_Min)) - 64
    hsbLetter.Min = m_Min
    PropertyChanged "Min"
End Property
Private Sub hsbLetter_Scroll()
    RaiseEvent Scroll
End Sub
Public Property Get Value() As String
    m_Value = hsbLetter.Value
    If m_ReturnCase = 0 Then
        Value = Chr(m_Value + 64)
    Else
        Value = Chr(m_Value + 96)
    End If
End Property
Public Property Let Value(ByVal New_Value As String)
    m_Value = New_Value
    m_Value = Asc(UCase(New_Value)) - 64
    hsbLetter.Value = m_Value
    PropertyChanged "Value"
End Property
Public Property Get ReturnCase() As Integer
    ReturnCase = m_ReturnCase
End Property
Public Property Let ReturnCase(ByVal New_ReturnCase As Integer)
    If New_ReturnCase > 1 Then New_ReturnCase = 1
    If New_ReturnCase < 0 Then New_ReturnCase = 0
    m_ReturnCase = New_ReturnCase
    PropertyChanged "ReturnCase"
End Property
`Initialize Properties for User Control
Private Sub UserControl_InitProperties()
    m_Max = m_def_Max
    m_Min = m_def_Min
    m_Value = m_def_Value
    m_ReturnCase = m_def_ReturnCase
End Sub

Another idea for an enhanced control is a type-ahead combo box. This type of combo box keeps the items in the drop-down list sorted and then performs a search on the item as the user types letters in the edit portion of the box. This type of feature makes the combo box easier to use for data entry.

From Here...

This chapter has shown you how to enhance existing controls to create new controls, and how to use the ActiveX Control Interface Wizard and Property Pages Wizard to make your control-creation work easier. To learn more about other topics covered in this chapter, see the following:


Previous chapterNext chapterContents


Macmillan Computer Publishing USA

© Copyright, Macmillan Computer Publishing. All rights reserved.