Using Visual Basic 6

Previous chapterNext chapterContents


- 26 -
Making Object-Oriented Programs with Visual Basic


Understanding User-Defined Types

Before you dive into the complexities of classes and objects, you need to understand user-defined types. As you go along, you'll learn that user-defined types and classes are very similar.

Throughout this book you've been using the intrinsic Visual Basic data types such as Integer, Double, and String. One advanced feature of VB is that it enables you to take the use of data types further by creating your own custom data type, known as a user-defined data type. You can think of a user-defined type as a variable that's broken into pieces for each part of the UDT that can be used repeatedly throughout your program.

Consider a program that stores the names of musical pieces and of the composer of each piece. You could keep track of everything by declaring variables grouped by a naming convention, as shown in Listing 26.1.

LISTING 26.1  26LIST01.TXT--Using Variable Naming to Keep Track of Related
Data

01 Public g_ComposerOne As String
02 Public g_PieceOne As String
03
04 Public g_ComposerTwo As String
05 Public g_PieceTwo As String
06
07 Public g_ComposerThree As String
08 Public g_PieceThree As String

This might work well in the short run, if you don't have many pieces to track. No matter what size your program is, however, you're relying on the naming of variables to define a structure that your program's data needs. An easier way would be to make a "package" of variables and give that package a name. This package is formally called a user-defined type. Then, you would create variables for your user-defined types by using the Dim, Public, or Private keywords.

You create a user-defined type by using the Type keyword in the General section of a module:

Type TypeName
     Elements as DataType
     ...
End Type

In this syntax,

You reference elements in the user-defined type by using the following syntax:

VarName.ElementName

In this syntax,

Listing 26.2 shows you how to create a user-defined type, Music, which encapsulates the composer and the piece. (If you want to follow along, this code is in project UserType.vbp, which you can download from http://www.mcp.com/info. At this site, enter the book's ISBN (078971633x) and then click the Search button to go to the Book Info page for Using Visual Basic 6. Listing 26.3 shows you how to create a variable of the Music user-defined type, named MyMusic (line 1).

LISTING 26.2  26LIST02.TXT--Creating a User-Defined Type

01 `Make a user-defined type that has
02 `elements for the composer and the piece
03 Type Music
04 Composer As String
05 Piece As String
06 End Type

LISTING 26.3  26LIST03.TXT--Implementing a User-Defined Type

01 Dim MyMusic As Music
02 Dim Msg$
03 `Assign values to each element in the user-
04 `defined type. Values come from TextBoxes on a form.
05 MyMusic.Composer = txtComposer.Text
06 MyMusic.Piece = txtPiece.Text
07
08 `Create a string that displays all of the
09 `values in the type
10 Msg$ = "Composer: " & MyMusic.Composer & vbCrLf
11 Msg$ = Msg$ & "Piece: " & MyMusic.Piece
12
13 `Display the string
14 MsgBox Msg$


Using user-defined types in Windows API programming

If you decide to pursue Windows API programming with Visual Basic, you can expect to be using user-defined types often. The Windows API is filled with hundreds of them.


Keep this in mind: Variables that are instances of user-defined types are subject to the same rules of scope as any other variable. Therefore, you might want to think about where your type will be used. Always plan ahead before declaring variables. You need to ask yourself if the variables will be local or global. If different areas of your program will share it, you need to make it global. However, if only certain areas of your program will need access to your variables, don't make them global.

Making Objects from Classes


Definitions of a data element

In the world of object-oriented programming, a data element is also known as a property, and a procedure is also know as a method. Other terms for property and method are attribute and behavior, respectively.


A class is similar to a user-defined type, except that in addition to having data, a class has procedures. A class is a collection of properties and procedures. An object is an instance of a class. For example, the user-defined type Music is defined as follows:

Type Music
    Composer As String
    Piece As String
End Type

Consider a procedure named Report:

Sub Report()
     Dim Msg$
    Msg$ = "Composer: " & Composer & vbCrLf
    Msg$ = Msg$ & "Piece: " & Piece
    `Display the string
    MsgBox Msg$
End Sub

Now consider that you could add the procedure to be an element of the user-defined type Music:

Type Music
    Composer As String
    Piece As String
    Report()
End Type

Next, you declare an instance of the type:

MyMusic as Music

Then you assign the values:

MyMusic.Composer = "Prince"
MyMusic.Piece = "Nothing Compares 2 U"

Thus, if you want to display the elements' values, you could call

MyMusic.Report()

Theoretically, this is what a class is about. However, things are trickier than this conceptual example illustrates: Scope plays a larger role, and the mechanics of Visual Basic demand that you create a class's properties and methods in a specific way.

Creating a Class in Visual Basic

A class is like an ActiveX control without a graphical user interface--you can use it, but you can't program it visually as you would an ActiveX control. As discussed earlier, you create objects from a class. The building block of a class is the class module.


Download this project

The code for this example is in the project smplmath.vbp, which you can download from http://www.mcp.com/ info, as explained earlier in this chapter.


Make a class with properties and a method that lets you add a number to a grand total

1. Create a new project and name it SmplMath.vbp. Rename the default form to frmMain. Set the value of the form's Caption property to Simple Math Class.

2. Choose Add Class Module from the Project menu.

3. Choose to begin a new project.

4. Set the class module's Name to CSmplMath. Make sure the Properties window is available and then save the class to the file CSmplMath.cls (see Figure 26.1).

FIGURE 26.1 Class modules are listed separ-ately in the Project Explorer.

5. Add a TextBox, CommandButton, and Label control to the form frmMain. Set the Name and Caption properties of the controls as shown in Table 26.1, and size and position the controls as you want them (see Figure 26.2).

TABLE 26.1  Control Names and Captions

Control Name Text Property Value
TextBox txtNum (leave blank)
CommandButton cmdAdd Add
Label lblAnswer (leave blank)

FIGURE 26.2 You enter data to be passed to a CSmplMath object through a form.

Adding Properties to a Class

So far, you've created the project structure of a form and a class module. You created an object as an instance of the class represented by the class module. Now you need to create the properties for the class. The class CSmplMath has two properties, NumToAdd and Total, both of type Integer. Figure 26.3 shows a diagram of the class CSmplMath and its properties. It also shows one internal Let and two internal Get procedures for the class, which will be discussed in a moment.

FIGURE 26.3 The scope of data and procedures is crucial when making a class. The only data that should be visible outside the class are the properties of the class.

Add properties to a class

1. Select the class module in the Code window.

2. Choose Add Procedure from the Tools menu.

3. Select the Property option in the Add Procedure dialog.

4. Add the property NumToAdd in the Name text box (see Figure 26.4). Click OK.

Notice that the Add Procedure dialog adds the Property methods Get NumToAdd and Let NumToAdd to the Code window, as shown in Figure 26.5.

FIGURE 26.4 When you use the Add Procedure dialog to add a property to a class, the Visual Basic IDE creates a Let and Get procedure for that property.

FIGURE 26.5 You set and access a class's internal data for a property by using the Let and Get procedures, respectively.

5. Add the property Total to your class module through the Add Procedure dialog, the same way you added the property NumToAdd.

6. Add the sub AddNum to the class module by using the Add Procedure dialog (see Figure 26.6). Make sure that the Sub option is selected.

FIGURE 26.6 If you set the scope of a sub to Public, it will be a method of the class. If you set the scope to Private, only the internal members of the class can use the sub.

7. Add the following code to the General section of the class module:

Private As Integer m_NumToAdd%
Private As Integer m_Total%


8. Complete the Get and Let procedures of the class module as well as the sub AddNum, as shown in Listing 26.4.

LISTING 26.4  Code for the CSmplMath Class Properties and Methods

01 Public Property Get NumToAdd() As Integer
02 NumToAdd = m_NumToAdd%
03 End Property
04
05 Public Property Let NumToAdd(ByVal iNewValue As Integer)
06 m_NumToAdd% = iNewValue
07 AddNumbers
08 End Property
09
10 Public Property Get Total() As Integer
11 Total = m_Total%
12 End Property
13
14 Public Property Let Total(ByVal iNewValue As Integer)
15 m_Total% = iNewValue
16 End Property
17
18 Private Sub AddNumbers()
19 m_Total% = m_NumToAdd% + m_Total%
20 End Sub
9. Go back in the class's Get and Let procedures in the code and change the Variant data types to Integers.

10. Save the code.

A lot is going on in this code. First, consider the functionality of the class CSmplMath, which has two properties, NumToAdd and Total. When you assign an Integer to NumToAdd, it's assigned through the internals of the class to a grand total. Then that grand total is internally transferred to the property Total.

Now consider the internals. In a class, you have Public data and procedures and Private data and procedures. Public data and procedures are what you've come to know as properties and methods. Private data and procedures are called member variables and member functions. This Public/Private schema is called encapsulation, a fundamental principle of object-oriented programming (OOP).


Specific ways of accessing Private data and functions

Get and Let are specific to Visual Basic. Other object-oriented languages use different ways of accessing Private data and functions.


In object-oriented programming, the program using the class doesn't work directly with Private data members or member functions. Instead, the program asks the class's Public procedures to access the data. The Public access procedures used by Visual Basic to access private data and functions are the Get and Let functions. Note that Visual Basic automatically handles property procedures differently from most object-oriented languages--they must be in a particular format with only certain arguments, or they won't work.

As you saw when you created the property NumToAdd, Get and Let property procedures were created to accommodate the property. Internal to the class are two private member variables, m_NumToAdd% and m_Total%, which you created in the General section. These variables hold the real data for class. The Let property procedure NumToAdd(iNewValue as Integer) passes in the runtime value of the property NumToAdd to the Private member variable m_NumToAdd% in line 6 of Listing 26.4. The runtime value is passed to the Let property procedure NumToAdd() as the argument iNewValue:

05 Public Property Let NumToAdd(ByVal iNewValue As Integer)
06     m_NumToAdd% = iNewValue
07     AddNumbers
08 End Property


Private member variables assignments

By convention, private member variables are assigned by the prefix m.


The Get property procedure of the property NumToAdd is Get NumToAdd() As Integer. This property procedure, which is a function, passes on the value of the associated private member variable m_NumToAdd% in line 2 to the property NumToAdd:

01 Public Property Get NumToAdd() As Integer
02     NumToAdd = m_NumToAdd%
03 End Property

The same principles apply for the property Total. The private member variable associated with Total is m_Total%. The Get and Let property procedures are Get Total() As Integer and Let Total(ByVal iNewValue As Integer), respectively. The internal works are

10 Public Property Get Total() As Integer
11    Total = m_Total%
12 End Property
13
14 Public Property Let Total(ByVal iNewValue As Integer)
15     m_Total% = iNewValue
16 End Property

The sub AddNum() is a procedure private to the class. This procedure adds the member variable m_NumToAdd% to m_Total%:

19 Private Sub AddNumbers()
20    m_Total% = m_NumToAdd% + m_Total%
21 End Sub 


Calling the class's property

When you set a value to an object's property, internally the object's class calls the associated Let property procedure. When you ask an object for a property's value, the internals call the Get property procedure.


This procedure is called within the Let property procedure Let NumToAdd(ByVal iNewValue As Integer) in line 7. In reality, this means that every time the program sets a number to the class's AddToNum property, the class sets the property's value to the private member m_NumToAdd%, as shown in line 6. Then the class calls AddNum() (line 7), which adds the member variable m_NumToAdd% to m_Total% (line 20).

When the program calls the class's Total property, the property procedure Get Total() As Integer returns the now incremented private member variable m_Total% to the class's Total property, as shown in line 11.

Creating an Object from a Class

Now that you've created a class, you can use an instance of it in your program as an object.

Create an object based on the class CSmplMath

1. Select the form frmMain from Project Explorer and then click the View Code button .

2. Add the code shown here to the General section of the form frmMain (see Figure 26.7).

Public gf_MyMath As New CSmplMath

FIGURE 26.7 If you want an object to persist throughout the life of the program, you must create it in the General section.

3. Add the following code to the cmdAdd_Click() event procedure:

gf_MyMath.NumToAdd = CInt(txtNum.Text)
    lblAnswer.Caption = CStr(gf_MyMath.Total)


4. Save and run the code.

You created your first object when you declared the variable gf_MyMath in the General section of the form frmMain. The syntax for creating an object is

Dim|Public|Private MyObject As New MyClass

In this syntax,

Thus, the statement

Public gf_MyMath As New CSmplMath

creates an object that you can use in your code, based on the class you made in the class module.

If you want to use this class in other projects, all you need to do is add the class module file CSmplMath.cls to the new project and then instantiate an object within the project's form or module by using the New keyword.

Making an ActiveX DLL

The class that you made earlier can be used only within the project if the .cls file is one of the project's files. If you want to make this class available to other programs at runtime as a separate DLL, you can do this by making the class an ActiveX DLL.


ActiveX DLLs are language independent

ActiveX DLLs are language independent. They can be written in any language that supports the Component Object Model (COM).


An ActiveX DLL can be complex, with implications far beyond this introductory exercise. The goal here is to give you a sense of what an ActiveX DLL is about by transforming the Visual Basic class that you made previously into one. If you want to know more about ActiveX DLLs, you can read about them in the Visual Basic Books Online documentation that comes with your copy of Visual Basic.

Make an ActiveX DLL by using your CSmplMath class

1. Create a new project. Select ActiveX DLL as the project type (see Figure 26.8).

FIGURE 26.8 When you select ActiveX DLL, the Visual Basic IDE automatically sets up the project.

2. Select the project in Project Explorer and name it CMathSrvr (see Figure 26.9). Save it to the file CMathSrvr.vbp.

FIGURE 26.9 The default name of the ActiveX DLL will be the name of the project, not the name of the class.

3. Right-click in the Project Explorer window. Choose Add from the context menu and then choose Add File.


Don't use the default class file

When you create an ActiveX DLL, you're provided with a default class file. If you want to make your class part of the project, you must add your class's .cls file.


4. Add the file CSmplMath.cls for your class, CSmplMath. (You can download the file from http://www.mcp.com/info.)

5. Right-click the default class file in the Project Explorer Class1.cls and choose Remove Class1.cls from the context menu.

6. From the Project menu, choose CMathSrvr Properties.

7. Enter Simple ActiveX DLL Demo in the Project Description text box (see Figure 26.10).

FIGURE 26.10 The Project Description text box describes your class to others when it's viewed in the Object Browser and the Tools/References dialog.

8. Select the class CSmplMath in Project Explorer. In the Properties window, set the Instancing property to 5 - MultiUse (see Figure 26.11).

You compile an ActiveX DLL as you would an executable. When you deploy it, use the Setup Wizard to ensure that all the accompanying runtime files are shipped with the DLL.

9. Choose Make CMathSrvr.dll from the File menu.

FIGURE 26.11 You can have many different types of Automation Servers. "MultiUse" means that all objects created from this class will share a single instance of the server.

You've just made an ActiveX DLL. Your class, CSmplMath, now resides in that DLL and can be used in Visual Basic just like any other ActiveX component. Before you can use the class, however, you must add the DLL to the Visual Basic IDE.

Add an ActiveX DLL to Your Visual Basic code

1. Create a new project and name it UserActvX. Rename the default form frmMain. Set the value of the form's Caption property to Using an ActiveX DLL.


Automated features of ActiveX in Visual Basic

Visual Basic automates a lot of the labor required to use ActiveX DLLs. In other languages such as C++, to use an ActiveX DLL, you must first find the DLL's type library (which describes the DLL to other programs). Visual Basic automatically makes and subsequently finds your custom ActiveX DLL's type library. Then VB presents the ActiveX DLLs to you in the References dialog.


2. Add a TextBox, CommandButton, and Label control. Set the Name and Caption properties as shown earlier in Table 26.1. Position the controls as you did for the form shown in Figure 26.2.

3. From the Project menu, choose References.

4. Make sure that the ActiveX DLL is listed in the Reference dialog by its description (see Figure 26.12). If it's not, click the Browse button to open the Add Reference dialog, navigate to the location where you saved the DLL CMathSrvr.DLL, and select the file.

FIGURE 26.12 If an ActiveX DLL is registered with your system, the classes in the DLL will appear in the References dialog. Otherwise, you need to select the DLL directly by using the Browse button. If you install the DLL using a Setup.EXE, the Setup process will register the DLL to your system.

5. To make the new classes in the ActiveX DLL available to your project, select the check box of the CMathSrvr class (it will be listed by its description, as in Figure 26.12). Then click OK.

6. Press F2 to display the Object Browser. Select the CMathSrvr class library from the drop-down list at the top left corner (see Figure 26.13).

FIGURE 26.13 The Object Browser enables you to look at all of a class's properties and methods within an ActiveX component.

7. Select the class CSmplMath from the classes list. Click the Copy icon at the top of the Object Browser.

8. Enter the following code into the General section of the project's only form, frmMain:

Public gf_MyMath As New


9. Paste the classname from the Clipboard to complete the line of code. If you don't want to paste the object from the Object Browser, you can select the object CSmplMath from the auto-complete drop-down list (see Figure 26.14).

FIGURE 26.14 When you add a class to the project, it automatically appears in the Methods/Objects drop-down list of the Visual Basic IDE.

10. Add the following code to the cmdAdd_Click() event procedure:

gf_MyMath.NumToAdd = CInt(txtNum.Text)
lblAnswer.Caption = CStr(gf_MyMath.Total)


11. Save and run the code (see Figure 26.15).

FIGURE 26.15 This program might seem identical to the one you made earlier, but it's not. This code is calling a class that's part of an external DLL, whereas the previous code compiled the class right into the executable.

Working with Components

On the Web site at http://www.mcp.com/info is a project named MthFuncs.vbp, which is the source code for an ActiveX component named SimpleMathFunctions. ActiveX component is a term for an Active DLL that contains one or more classes.

The SimpleMathFunctions component is an enhancement of the work you did with CSmplMath. SimpleMathFunctions contains the class CMathFunc. CMathFunc publishes three properties: NewValue, Operation, and TotalValue. It also publishes one method, DoOperation.

The way the class works is that you set a numeric value to the property NewValue, and then you set a value to the property Operation. Operation can take one of four values:

0 - Addition

1 - Subtraction

2 - Multiplication

3 - Division


Mastering OOP with ActiveX DLLs

Making ActiveX DLLs requires mastery of object-oriented programming. You might want to start by making a few class modules first to get the hang of things. Then, when you have a clear understanding and facility in that arena, you can expand these skills by working with ActiveX DLLs.


After the NewValue and Operation properties are set with appropriate values, you invoke the DoOperation method. The result will be displayed in the read-only property TotalValue.

This ActiveX component is an advanced demonstration of ActiveX DLLs. Remember when you use this code to make sure that the DLL is registered to your system or included in the Visual Basic IDE. Remember to use the Add Reference dialog to make the component available to your program.

ActiveX DLLs are a key part of Microsoft's Distributed Computing Technology. Not only can you design ActiveX DLLs to reside on a desktop computer and to be used by applications on that desktop computer, but you can make ActiveX DLLs that reside on remote computers and are accessed by local computers. You can even make Active DLLs that can run on Microsoft's Internet Information Server as components or IIS applications.


Previous chapterNext chapterContents

© Copyright, Macmillan Computer Publishing. All rights reserved.