Skip to Main ContentWindow-Eyes  Braille Sense  CCTV  Voice Sense  SyncBraille  Support  Training
GW Micro - Unleashing the power of your mind's eye.
 

Using Class Based Event Handlers - GWWiki

Revision as of 14:29, 2 April 2012 by Root (Talk | contribs)
Jump to: navigation, search

Classes are a common approach for keeping track of and modifying data, but they can also be used as a convenient way to create a stateful process of acting upon some given data.

Class properties can be as simple as:

 Public MyProperty

If your instantiation of your class was an object called MyObject, you could set and retrieve the property with:

MyObject.MyProperty = "hello" ' setting the property
MsgBox MyObject.MyProperty ' getting the property

Class methods, which are just subs and functions, are also fairly easy to access:

Public Class Hello()
 MsgBox "Hello. How are you today?"
End Class

The method would be accessed via:

MyObject.Hello()

Handling events inside of a class, on the other hand, is slightly more complicated.

When you connect to an event in Window-Eyes, you typically pass the name of the function, such as:

ConnectEvent Application, "OnHotkey", "MyHotkeyProc"

You can also pass the address of a function, using:

ConnectEvent Application, "OnHotkey", GetRef("MyHotkeyProc")

Window-Eyes handles obtaining the address of your function for you, which is typically why you don't find GetRef used when connecting to events. Another thing Window-Eyes will do for you is obtain the default method of an object, and use that as the event function. For example:

ConnectEvent Application, "OnHotkey", MyObject

Armed with that knowledge, you may begin to see how you can create a class designed to handle events within itself.

Class MyClass
 Private myEventHanvler

 Public Default Sub EventHandler(Window)
   ' Do something with the Window
 End Sub

 Public Sub Class_Initialize()
   myEventHanvler = ConnectEvent(DesktopWindow, "OnChildActivate", Me)
 End Sub

 Public Sub Class_Terminate()
   Disconnect myEventHanvler
 End Sub
End Class

When you instantiate MyClass, you'll have an object that handles window activations. You could use this object for any window event, or, really, any event whose parameter count matched that of the event handler.

What if you wanted to handle events that passed different numbers of parameters? Since you can only designate one class method as being the default, you would need to create a way to mediate the events with their respective handlers. You can do that by creating a proxy class responsible for marshaling the call between the proxy class and the class containing the event handler. An example may help clear things up.

Class EventHandlerClass
	' Declare private variables
	Private winEventHandler
	Private winEventProxy
	Private speechEventHandler
	Private speechEventProxy

	Public Sub Class_Initialize() ' Class constructor
		' Each of these "proxy" variables contain an instantiated copy of the
		' respective proxy class, followed by a call to that object's Init
		' method, passing a copy of this EventHandlerClass, and the name of the
		' method used as the event handler.
		Set winEventProxy = (New SingleParameterProxyClass).Init(Me, "WinProc")
		Set speechEventProxy = (New DualParameterProxyClass).Init(Me, "SpeechProc")
	End Sub

	Public Function Init()
		' This method connects to the events we're interested in using the
		' appropriate proxy object as the event handler.
		winEventHandler = ConnectEvent(DesktopWindow, "OnChildActivate", winEventProxy)
		msaaEventHandler = ConnectEventWithParameter(Speech, "OnSpeak", speechEventProxy, Now())
		Set Init = Me
	End Function

	Public Sub WinProc(wObj)
		' Window event handler
	End Sub

	Public Sub Speechproc(originalString, speakTime)
		' Speech event handler
	End Sub

	Public Sub Dispose()
		' This method helps ensure that the events are disconnected correctly.
		' It should be called before the instantiated EventHandlerClass is
		' disposed of.
		If winEventHandler <> 0 Then
			Disconnect winEventHandler
		End If
		If speechEventHandler <> 0 Then
			Disconnect speechEventHandler
		End If
	End Sub

	Public Sub Class_Terminate() ' Class destructor
		Set winEventProxy = Nothing
		Set speechEventProxy = Nothing
	End Sub
End Class

' The SingleParameterProxyClass marshals calls to the specified function inside
' the caller. This particular class deals events or procedures that take a
' single argument.
Class SingleParameterProxyClass
	Private caller
	Private functionName

	' VBScript doesn't appear to report the default method correct,
	' so we need to make sure that it's defined first.
	Public Default Sub Main(parm1)
		Eval "caller." & functionName & "(parm1)"
	End Sub

	Public Function Init(c, fn)
		Set caller = c
		functionName = fn
		Set Init = Me
	End Function
End Class

' DualParameterProxyClass - marshals calls to the specified function inside the
' caller. This particular class deals events or procedures that take two
' arguments.
Class DualParameterProxyClass
	Private caller
	Private functionName

	' VBScript doesn't appear to report the default method correct,
	' so we need to make sure that it's defined first.
	Public Default Sub Main(parm1, parm2)
		Eval "caller." & functionName & "(parm1, parm2)"
	End Sub

	Public Function Init(c, fn)
		Set caller = c
		functionName = fn
		Set Init = Me
	End Function
End Class

' You can now instantiate the EventHandlerClass, and begin using it for
' handling the designated events.
Dim myEventHandler : Set myEventHandler = (New EventHandlerClass).Init()

' Connect to the ClientInformation shutdown event so that the event handler
' can be cleaned up nicely before exiting.
ConnectEvent ClientInformation, "OnShutdown", "OnShutdown"
Sub OnShutdown()
	If Not myEventHandler Is Nothing Then
		myEventHandler.Dispose()
	End If
End Sub


Text Size:
Decrease Text Size Increase Text Size

Personal tools

Powered by MediaWiki
Public Domain
© 2013 GW Micro, Inc. All Rights Reserved.
GW Micro, Inc.    725 Airport North Office Park    Fort Wayne, IN 46825
Ph: 260-489-3671 Fax: 260-489-2608    www.gwmicro.com    sales@gwmicro.com    support@gwmicro.com
Hours: M-F, 8a-5p, EDST