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.
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).
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
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 programmingIf 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.
Definitions of a data elementIn 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.
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 projectThe 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
FIGURE 26.1 Class modules are listed separ-ately in the Project Explorer.
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.
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
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.
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.
Private As Integer m_NumToAdd% Private As Integer m_Total%
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
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 functionsGet 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 assignmentsBy 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 propertyWhen 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.
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
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.
gf_MyMath.NumToAdd = CInt(txtNum.Text) lblAnswer.Caption = CStr(gf_MyMath.Total)
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.
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 independentActiveX 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
FIGURE 26.8 When you select ActiveX DLL, the Visual Basic IDE automatically sets up the project.
FIGURE 26.9 The default name of the ActiveX DLL will be the name of the project, not the name of the class.
Don't use the default class fileWhen 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.
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.
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
Automated features of ActiveX in Visual BasicVisual 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.
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.
FIGURE 26.13 The Object Browser enables you to look at all of a class's properties and methods within an ActiveX component.
Public gf_MyMath As New
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.
gf_MyMath.NumToAdd = CInt(txtNum.Text) lblAnswer.Caption = CStr(gf_MyMath.Total)
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.
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 DLLsMaking 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.
© Copyright, Macmillan Computer Publishing. All rights reserved.