VBScript doesn't have an event implementation so if you fancy having features like attaching handlers which will respond to specific events on your object you can do it simply by using the GetRef function and a bit of "syntactic sugar".
I'm using ASP in these examples cos it's easy.
Example 1 - Simple Events
'Create a handler Function MyHandler() Response.Write "Hello from the handler!" End Function 'Create an event Dim OnLoad Set OnLoad = GetRef("MyHandler") 'Fire the event OnLoad()
Here we've created a simple event which takes one handler function and fired the event which in turn has called the function we attached.
To turn this in to a more useful event system we can use an array for the OnLoad event variable thus...
'Create some handlers Function MyHandler1() Response.Write "Hello from handler 1!" End Function Function MyHandler2() Response.Write "Hello from handler 2!" End Function 'Create an event Dim OnLoad OnLoad = Array(GetRef("MyHandler1"), GetRef("MyHandler2")) 'Fire the event For Each handler In OnLoad handler() Next
Example 2 - Event Arguments
In most event implementations the event handlers take one argument, passed to them by the fired event, which contains things like the type of event and a reference to the object on which it was fired etc.
'Create a handler which takes one argument Function MyHandler(e) Response.Write "Hello from the handler - i was called by " & e End Function 'Create two events Dim OnLoad Set OnLoad = GetRef("MyHandler") Dim OnUnload Set OnUnload = GetRef("MyHandler") 'Fire the events OnLoad("Load") OnUnload("Unload")
Wrapping it up
We've established we can do all the basics of events, now all we need to do is wrap it up in a few classes to make it usable.
First we need an Event class that we can instantiate for each event we want. This will have to expose an event arguments property and methods for attaching handlers and firing the event. It will also have to keep track internally of the attached handlers. Lets have a go...
Class clsEvent 'An array to keep track of our handlers Private aryHandlers() 'Our event arguments object to be passed 'to the handlers Public EventArgs Private Sub Class_Initialize() ReDim aryHandlers(-1) Set EventArgs = New clsEventArgs End Sub Private Sub Class_Terminate() Set EventArgs = Nothing Erase aryHandlers End Sub 'Method for adding a handler Public Function AddHandler(strFunctionName) ReDim Preserve aryHandlers(UBound(aryHandlers) + 1) Set aryHandlers(UBound(aryHandlers)) = _ GetRef(strFunctionName) End Function 'Method for firing the event Public Function Fire(strType, objCaller) EventArgs.EventType = strType Set EventArgs.Caller = objCaller For Each f In aryHandlers f(EventArgs) Next End Function End Class
Next we need an EventArgs class for passing data about the event to the handlers. This just needs three properties; event type, caller and an arguments collection for event type specific things.
Class clsEventArgs Public EventType, Caller, Args Private Sub Class_Initialize() Set Args = CreateObject("Scripting.Dictionary") End Sub Private Sub Class_Terminate() Args.RemoveAll Set Args = Nothing End Sub End Class
Next our class that has an event, in this case an OnLoad which fires after the object's Load method is called. We'll also create a few handlers and do a trial run.
Class MyClass Public OnLoad Private Sub Class_Initialize() 'Setting up our event Set OnLoad = New clsEvent 'Adding an argument OnLoad.EventArgs.Args.Add "arg1", "Hello" End Sub Public Function Load() Response.Write "loading the object here!<br />" 'Firing the event OnLoad.Fire "load", Me End Function End Class 'A couple of handling function for the events Function EventHandler(e) Response.Write "<h2>EventHandler</h2>" Response.Write "<p>Event """ & e.EventType & """ fired by object of type " & TypeName(e.Caller) & ".</p>" End Function Function EventHandler2(e) Response.Write "<h2>EventHandler2</h2>" For Each x In e.Args Response.Write x & ": " & e.Args(x) & "<br />" Next End Function 'instantiate the object, attach the handlers and call the load Set myObj = New MyClass myObj.OnLoad.AddHandler("EventHandler") myObj.OnLoad.AddHandler("EventHandler2") myObj.Load()
Event based programming reverses the responsibility for code execution within your program. In conventional procedural programming it would be the responsibility of the myObj class to make sure the two event handlers were fired when it's Load method was called. By using an OnLoad event instead myObj doesn't have to know anything about the environment in which its executing, it just blindly fires the event and any attached handlers will be called. In this way you can add additional functions which run when myObj's Load method is called without modifying MyClass.
In more complex systems being able to add functionality with a minimum of intrusion into other parts of the system is a big bonus and event based programming is an easy way of achieving it.