Solved

Events in class which Implements interface

Posted on 1998-09-17
9
325 Views
Last Modified: 2013-11-25
Preface:
-------
I am trying to create the abstract "parent" class and 10 "descendant" classes. Each Implements "ancestor" interface. In main form I need to create and use an instance of one of the 10 classes depending on the user's choice.
--------
Question:
--------
How to use events? I tried to declare events like that
Public Event Error(Msg As String)
in both abstract class (clsConverter) and descendant. But when I declare
Private WithEvents Converter As clsConverter
and try to create
Set Converter = New clsDescConverter
I got the error message with the following help
"You tried to use a WithEvents variable with a component that can't work as an event source for the specified set of events. For example, you may be sinking events of an object, then create another object that Implements the first object. Although you might think you could sink the events from the implemented object, that isn't automatically the case. Implements only implements an interface for methods and properties.

You can't sink events for a component that doesn't source events."
What could be the possible solution of this problem?
0
Comment
Question by:dksqrt
  • 3
  • 3
  • 2
  • +1
9 Comments
 

Expert Comment

by:sjrl
ID: 1435406
I think you would have to have an object reference to the clsDescConverter in order to sink its events. This reference would have to be of the clsDescConverter type not the clsConverter type. The clsConverter doesn't know the interface of clsDescConverter and therefore cannot sink its events.

0
 

Author Comment

by:dksqrt
ID: 1435407
But having to declare all descendants WithEvents instances and sink is a nightmare!
I have 10 classes and 4 events I would have to write 10 declarations and 40 handlers! 40 handlers which do *the same* handling!
Any other ideas? I can reorganize code any way I want to but writing 10 copies of the same procedure - it's just disgusting from the OOP and even structured programming point of view...
What does "isn't automatically the case" in the previous help message mean? Perhaps some solution is possible?
And all my 4 events are *declared* in clsConverter and
clsDescConverter **Implements** clsConverter interface.
Why "The clsConverter doesn't know the interface of clsDescConverter and therefore cannot sink its events." ?
0
 

Expert Comment

by:sjrl
ID: 1435408
Have one class CMainClass which fires the events and does any computation common to call classes and has a property which is an IConverter object (ie class implementing the IConverter interface). You can sink events from this class. To allow for the difference in converters you set the IConverter parameter of the CMainClass to be clsDescConverter say. Then when CMainClass needs to do anything it can call the methods of the clsDescConverter class you passed it.

Suppose that you define a Convert method in the IConverter interface.
Give the CMainClass a property of type IConverter, call it converter.
Suppose you want to use the clsDescConverter. You set the CMainClass.Converter property to a clsDescConverter object.
Then when you call the Convert method of the CMainClass object, it would call the converter objects Convert method (which would be there because it is a part of the IConverter interface).

Hope this helps.
0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 

Expert Comment

by:sjrl
ID: 1435409
I've just realised I left an unanswered question.

clsDescConverter implements the clsConverter interface which is how it knows what that interface is. The clsConverter is the base object. It doesn't know anything about the clsDescConverter objects interface.
0
 

Author Comment

by:dksqrt
ID: 1435410
Yes it is unanswered
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1435411
There is not a solution to this problem.
This has to do with the way COM works and the way VB implements events. The events and the method are actually two different objects in COM.
With implements you implements only the method and the properties. You cannot inherited the events.
0
 

Author Comment

by:dksqrt
ID: 1435412
I got your point. But could you suggest any posiible workaround?
I have the pretty concrete task and I can design all involved classes anyway I want.
If it's not possible to have RaiseEvent-s in inherited classes - how to live without them?
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1435413
Pass the parent object to the interface.

clsConverter.Init me

and make the caller implement clsConverterCallback interface.
These are the event methods.

0
 

Accepted Solution

by:
prince_merlin earned 130 total points
ID: 1435414
You can implement the following workaround:

1. Create the parent object (Public Inherited As clsConverter) in each child. (in child's Class_Initialize())
2. Implement interface as usual without events.
3. Define events in the parent and create one additional procedure for each event in the parent class.

Public Sub RaiseMessage(Msg As String)
  RaiseEvent Message(Msg)
End Sub
4. Copy and paste these procedures in each child replacing the call inside to Call Inherited.RaiseMessage(Msg).
5. Replace all occurences of RaiseEvent Message(Msg)
in child classes to RaiseMessage(Msg)
6. Sink events in the form you need (such as the main form of a program) like this:

Private WithEvents GenConverter As clsConverter
.
Set Converter = New clsDescConverter
Set GenConverter = Converter.Inherited
'Ready to work - events will be sinked
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question