Microsoft & .NETVisual BasicA Beginner's Guide to COM Interfaces

A Beginner’s Guide to COM Interfaces

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Before the release of Visual Basic 5, many people could be heard saying COM?? Now professional developers are laughed at if they don’t know what COM stands for. Well, it stands for the Component Object Model. In this article I will take you through using COM Interfaces with class modules to create an object orientated program. As we go along, I will try and explain some confusing terms and how they are useful.

Visual Basic makes using COM Interfaces much much
easier then C++. In C++ you have to worry about sorting through a mound of information on
GUIDs (Globally Unique IDs) and other complicated procedures and functions. Visual Basic
takes care of most of this low level stuff, leaving us to have some fun.

When I first heard of COM, Interfaces and Objects I
thought I had just landed on planet mars. And to tell the truth, not many other developers
actually really understood these terms. So, I grabbed a copy of Deborah Kurata’s award
winning book, Doing
Objects in MS Visual Basic
. This book uses her no jargon style writing to clearly
explain object orientated programming, including COM. I suggest you take a look.

At the time, many people were asking why should we
use COM Interfaces/Objects? Well, the simple answer is that it saves time. One of the
points of object orientated programming is code reuse, and, as I explain our demo project,
you will see that it creates reusable class modules.

So far I have outlined the background of COM
Interfaces etc and you are still wondering what is a COM Interface? Well, an Interface is
a way of publishing a set of properties and methods so that other programs can interface
with your application through COM. This can be seen in the highly popular VBA scripting
language found in most new Microsoft products. To see this in action, open VB, add a
reference to the Microsoft Word 8 Object Model, and load up the Object Browser. From the
Libraries combo box select Word. Take a look at the properties and methods that it
exposes.

To use an interface within your own program you
need to use class modules. First of all you create a class that contains only methods and
member variables, except you place no code within these methods. This class will be
implemented into another class. Let me explain. Say this first class is called IDataOject,
and it contains a GetInfo and Save method. Well, you will want another class to take on or
‘implement’ IDataObject’s methods and properties. We do this by using the Implements
keyword. We now have another class that implements the IDataObject interface.

I know what you are saying now, why on Earth is
this useful? Well, instead of spending another ten pages explaining it, here is a little
example.

Open VB and create a new Standard EXE Project.
Click Project, Add Class Module. Repeat this. Also Click Project, References. Select
Microsoft DAO 3.51 Object Library. Now you should have two class modules. Rename the first
IDataObject and the second CPerson. To the IDataObject add the following code:

Option Explicit

Public IsChanged As Boolean

Public Sub Save()
End Sub
Public Sub GetInfo()
End Sub

Open the second class, CPerson and add the
following code:

Option Explicit

Implements IDataObject

Private m_db As Database
Private m_rs As Recordset

Private m_lngID As Long
Private m_strName As String
Private m_strAddress As String
Private m_blnChanged As Boolean

Private Sub Class_Initialize()
Set m_db = OpenDatabase(App.Path & "people.mdb")
End Sub

Private Sub Class_Terminate()
m_rs.Close
m_db.Close
Set m_rs = Nothing
Set m_db = Nothing
End Sub

Private Sub IDataObject_GetInfo()
If ID = 0 Then
Err.Raise vbObjectError, "CPerson", "A valid ID must be set before
attempting to retrieve data."
End If

Set m_rs = m_db.OpenRecordset("SELECT * FROM People WHERE ID =" & ID)

Name = m_rs.Fields("Name").Value
Address = m_rs.Fields("Address").Value
End Sub

Private Property Let IDataObject_IsChanged(ByVal RHS As Boolean)
m_blnChanged = RHS
End Property

Private Property Get IDataObject_IsChanged() As Boolean
IDataObject_IsChanged = m_blnChanged
End Property

Private Sub IDataObject_Save()
If ID <> 0 Then
m_rs.Edit
Else
m_rs.AddNew
End If

m_rs.Fields("Name").Value = Name
m_rs.Fields("Address").Value = Address
m_rs.Update
End Sub

Public Property Get ID() As Long
ID = m_lngID
End Property

Public Property Let ID(ByVal NewID As Long)
m_lngID = NewID
End Property

Public Property Get Name() As String
Name = m_strName
End Property

Public Property Let Name(ByVal NewName As String)
m_strName = NewName
End Property

Public Property Get Address() As String
Address = m_strAddress
End Property

Public Property Let Address(ByVal NewAddr As String)
m_strAddress = NewAddr
End Property

As you can see we are using a database to store the
CPerson information. We have used DAO 3.5 for this although you can modify it to whatever
data access you want. Notice that all the methods and properties have been implemented.
This is neccessary when implementing an interface otherwise you will run into errors. Take
a closer look at the IDataObject_Save method. If the ID is 0, then it is not a current
record and therefore a new one needs to be added. Also take a look at the
IDataObject_GetInfo method. As with all code in class modules, you should always raise the
error and let the module / form / usercontrol handle the error.

The clever bit is now in the form’s code. On the
form add two command buttons (cmdGet and cmdSave) and a text box (txtName). In the General
Declarations procedure declare these two variables:

Private Person As CPerson
Private DataObj As IDataObject

The best code is in the Form_Load procedure. What
we are going to do is to create a new instance of the CPerson class, and set the DataObj
variable to the new CPerson instance. What this does is it makes both variables point to
the same object, that is IDataObject. But Person also points to CPerson. So if you want to
interface with the database, use the DataObj variable and if you want to interface with
the person information use the Person variable. To demonstrate this, copy the following
code into the form:

Private Sub cmdUpdate_Click()

If DataObj.IsChanged Then
Person.ID = 1
Person.Name = txtName
DataObj.Save
End If

End Sub

Private Sub cmdGet_Click()
Person.ID = 1
DataObj.GetInfo
txtName = Person.Name
End Sub

Private Sub Form_Load()
Set Person = New CPerson
Set DataObj = Person
DataObj.IsChanged = False
End Sub

Private Sub txtName_Change()
DataObj.IsChanged = True
End Sub

This reads in the first record (cmdGet) into
txtName where you can change it (and if you do then it sets the IsChanged flag to True).
Then the cmdSave button saves the new name if the IsChanged flag is True.

You can now create multiple classes that implement
the IDataObject interface very quickly and easily. Take a look at the example below.

Now that you have made your first COM Interface you
will be wanting to look for some more examples. Well, look to http://www.eastwood60.freeserve.co.uk/
and download either version 1 or version 2 of the VBCodeLibrary project. The source code
demonstrates how to use DAO 3.5 data access with COM Interfaces and Objects. Take a look,
as it should help you out.

That’s it from me this time, and I hope you
understand COM Interfaces a bit better now. If you have any comments on this article then
please email them to me at shugill@domain.softnet.co.uk
or drop in on my Visual Basic web site at http://www.vbsquare.com/

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories