Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use WithEvents keyword with global variable?

I am trying to declare a variable in a VB6 module as follows:

Public WithEvents MyObject As MyClass

The help files say that WithEvents can only be used in class modules. Why can't it be used in .bas modules?

The legacy code I am working has an object declared globally in a module. I want to add WithEvents to this declaration but I need to keep the object global because many other forms etc refer to the object. How can I achieve this with minimal disruption to the code?

like image 995
CJ7 Avatar asked Aug 28 '12 04:08

CJ7


2 Answers

Write a class that accepts your global object as a parameter and sinks its events.

' Class MySink
Private WithEvents m_oSink As MyClass

Friend Sub frInit(oSink As MyClass)
    Set m_oSink = oSink
End Sub

Private Sub m_oSink_MyEvent()
    '--- implement event
End Sub

Create an instance of this class in your .bas module.

Public g_oMyObject AS MyClass
Private m_oMySink As MySink

Sub Main()
    Set g_oMyObject = New MyClass
    Set m_oMySink = New MySink
    m_oMySink.frInit g_oMyObject
End Sub
like image 173
wqw Avatar answered Sep 27 '22 23:09

wqw


Events in VB are a wrapper around a fairly complicated COM mechanism. Essentially in this mechanism, everything involved has to be a COM class implementing the interfaces IConnectionPoint or IConnectionPointContainer. A BAS module is a part of legacy BASIC, and is not implemented as a COM class, unlike the VB class. I suppose that they could have reimplemented a BAS file in COM as a singleton type object (like they do with Global MultiUse classes), but they didn't. So, unfortunately BAS files cannot use WithEvents.

As for the simplest solution to your problem - you need to take advantage of the fact that object variables are just references to the object, and not the object themself. I imagine you want your event messages to get to the highest level object that is necessary, in order for your to have the means to control the bit of the application you are interested in. Identify this place. For instance, it could be that you have a main form that you are sure will be the first object loaded, and the last unloaded. As part of initialisation of this object, pass in a reference to your global object, and set this to a WithEvents module level variable. You are now in control.

BUT!! And this is very important!! You must ensure that you clear down this reference in good time before the application closes, just in case you have any circular references to your form (or whatever). The Form_Unload event would be ideal in this case.

like image 45
Mark Bertenshaw Avatar answered Sep 27 '22 23:09

Mark Bertenshaw