logo
vbRad Home
Source Code
Book Reviews
Forum
Links
About Us
Contribute

Compare Databases with SQL Effects Clarity
 
 Expose events from implemented classes

Posted on
4/20/2001
Author:
Robert Gelb
Email:
Not Shown
Applies To OS:
NT, 9x, 2000
Product:
5, 6



Download the source code (4 kb) for this article

Using Implements cClass is great. You get to define an interface, safely store it away and then create classes based on this interface. Visual Basic even creates a code stub for you. Almost a no-brainer. It is useful for situation where your classes might have an identical interface but different implementation. For instance, I used to have several classes that did some low-level maintanance on Sybase and Microsoft SQL Servers and Access database. Each of them had an identical interface. This was a perfect place to use Implements technology.

Unfortunately, it has one small caveat - you can't expose events from either the parent or the child class. Consider the following - you have your Interface class (IDatabaseMaintanance), you have your implemented classes (CDatabaseMaintanance_Sybase, CDatabaseMaintanance_MSSQL and CDatabaseMaintanance_Access) and you have your client app. You expose the following properties and events in the Interface class (IDatabaseMaintanance)

Public dbName as String
Event StartProcessing(Status as String)
Event Processing(Status as String)
Event EndProcessing()
In the client app you instantiate iClass using WithEvents
'(general declarations)
Private WithEvents o As iClass
Then in some sub you attempt to instantiate the implemented class
set o = CreateObject("dbMaint.CDatabaseMaintanance_Sybase")
And you'll get an error stating that this class doesn't support the set of events.

Too bad. It would be sweet to be able to expose events. Fear not, there is a workaround. But you have to take another tack with it. Create 3 projects: one is a Standard Exe (Client), second one is for the interfaces and it will have 2 classes - the primary interface (IClass) and a secondary one which we will use to create events (IEvents). The 3rd project will be an ActiveX DLL and will contain just one class (CClass) which will implement IClass. In the Client project, add references to the 2 and 3 projects. In the last project, add references to the project with all the interfaces.

First, let's define all the events. In IEvents, type the following:
Public Sub StartProcessing(Status as String)
End Sub

Public Sub Processing(Status as String)
End Sub

Public Sub EndProcessing()
End Sub

Now let's define the interface for IClass. Note the parameter to the Execute method

Public FirstName as String
Public LastName as string

Public Sub Execute(oEventsInterface as IEvents)

End Sub

So basically, whoever implements IClass will have the opportunity to fire off methods on the IEvents interface. This will come into play later. Meanwhile, let's implement IClass in CClass (3rd project)

Implements IClass

Public Sub IClass_Execute(oEventsInterface as IEvents)
    'fire off the StartProcessing method on the oEventsInterface
    oEventsInterface.StartProcessing "In Progress"
End Sub

You may ask at this point, StartProcessing was executed but where will it fire? Good question. Hold on. In the Client project, in the General Declarations implement the IEvents. Then in the Form_Load will fire off the whole thing

Implements IEvents
Private Sub Form_Load()
'define the object
Dim o as IClass

'now create it from the implemented class
Set o = CreateObject("Project3.CClass")

'now send the form as the target for IEvents methods
o.Execute (Me)

Set o = Nothing
End Sub

Private Sub IEvents_StartProcessing(Status as String)
    'This is where the event will fire
End Sub

The code is kind of weird, but it works, thanks to COM's engine. I realize that it is kind of difficult to explain - but really easy to follow in code. So download it and give it a whirl.

Thanks to Jason Bock for pointing me in the right direction.





Add Your Comment  

Name: Email Address: all fields optional
Notify me via email when someone responds to this message (valid email required).

Enter the word: