How does VB6 define an event for an object array?

Source: Internet
Author: User
During the course of your programming, if you have used classes at all you will probably have also used the keyword Withevents . Withevents Is used when declaring an object variable, to indicate that you also wish to receive events raised by that object. it is nice because you can then use the object variable just like a control on a form, doesn't that it can be used in a class.

Private withevents myobject as someclass

You have probably also used arrays of object variables too. this comes in handy when you want to manage multiple objects cleanly, as you can loop through them and carry out the same actions to each in turn (see this thread for an explanation of arrays ).

Private myobjects () as someclass

Now the trouble comes when you, as happens eventually, want to combine the two. you need to handle events from your objects, but you also need to have an array of them, and handle events from all of the object instances. since programmers are inherently logical, you 'd try this:

Private withevents myobjects () as someclass

... And VB will give you a nice, helpful, error message that tells you exactly why it isn' t allowed.

now really the reason why you cannot use withevents on an array of objects is quite simple-if you had a single event handler for each object, you wowould have no way of knowing which object fired the event. you will probably have noticed that event handlers for controls that are part of control arrays will have an extra index parameter-this is because control arrays were specified before the days of COM and it required some fair hacking on Microsoft's part to add the index property to control events under the com system. this same hacking cocould not be done for arrays of objects, because the objects do not have index properties-Your array simply holds references to each object.

so do we give up? No... of course there is always a solution in this case it's one that sounds complex, but in reality (and you'll see an example of it) It's not too hard. I am going to offer two solutions-one for classes that you create yourself, and one for those that you do not have the source.

If you have the source it's easy. first you need to get rid of all events-since we can't use them. you can replace the raiseevent callwith callto named methods in your event-handling class or form, that will form the new event handlers. now you run into the first potential problem which is that these methods may not exist. to ensure that they do, we will have to require that the event-handling class/FormImplementsAn interface class which defines all of our events and their parameters. implementing an interface means that the class/form will have to contain all the event handling methods, so we eliminate the possibility that they do not exist when we are trying fire to an event.

You define an "Event" in the interface class like this:

Sub myevent (anyparams)
End sub

Note that it is not necessary for the function body to be empty, but whatever you put in there we are not going to use anyway.

Once you 've defined all events you then need to know where to send them. for that purpose we can define a property in our custom class. note that we type this property as the type of our event interface-that forces potential event handling classes to contain the proper event handlers and eliminates any possibility of errors on our side-it is up "Them" to ensure that they meet the requirements private mcallback as imyeventinterface

Property set callback (newobj as imyeventinterface)
Set mcallback = newobj
End Property

Property get callback () as imyeventinterface
Set callback = mcallback
End Property

Now to raise an event we can simply call the appropriate event handler in our "Callback" class. of course, we must first check to see if it exists-if no callback class has been set, we cannot call anything (obviusly)

'Raise an event
If (not mcallback is nothing) Then _
Mcallback. myevent anyparams

And finally we want to implement an array of the classes-and now you can see the final solution that does not useWitheventsImplements imyeventinterface

Private myobject () as someclass

Private sub form_load ()
Redim myobject (5)
For I = 0 to 5
Set myobject (I) = new someclass
Set myobject (I). Callback = me
Next I
End sub

Private sub imyeventinterface_myevent (anyparams)
'Ur event handler
End sub

Now you might recall I mentioned a solution for classes for which you do not have the source code for, such as classes in DLLs. well here you can apply a bit of creative adaptation of the first solution. my someclass class is now going to a "wrapper" class for the Closed-source class-so called because it will contain a reference to an instance of this class, but we will be using the Wrapper class to access it. the instance of the closed-source class will need to be declared using Withevents , Because you can't change the way it raises events. however you still have the same setup in place for your callback and interface (you will need to include in your interface all events of the closed-source class that you handle in your Wrapper class) -So you can declare an array of Wrapper Classes and use them to handle the events from the "wrapped" classes.

You will need to also add a property so that you can access the wrapped class.

Private withevents mwrapped as wrappedclass
Private mcallback as imyeventinterface

'Callback () Property snipped...

Property set wrapped (newobj as wrappedclass)
Set mwrapped = newobj
End Property

Property get wrapped () as wrappedclass
Set wrapped = mwrapped
End Property

'For each event handled, raise a new one by the callback Method
Private sub mwrapped_someevent ()
If (not mcallback is nothing) Then _
Mcallback. someevent
End sub

Now you use the Wrapper class, something like this:

Implements imyeventinterface
Private myobject () as someclass

Private sub form_load ()
Redim myobject (5)
For I = 0 to 5
Set myobject (I) = new someclass
Set myobject (I). Callback = me
Set myobject (I). Wrapped = new wrappedclass
Next I
End sub

Private sub imyeventinterface_someevent ()
'Event Handler
End sub

Hopefully that gives you the idea of how to handle events raised from arrays of objects, both for your own and for compiled classes. so that you can see I'm not spouting Bilgewater I have also included a demonstration of the first technique. you will need an extraction program such as WinZip or 7-zip to unzip the file, and then run the extracted project. I have commented the code so that you can (H Opefully !) Understand what's going on

Attached files
Withevents for arrays, by penagate.zip (3.8 kb, 331 views)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.