Object wrappers and Event sinks
A very simple example of wrapping a control is to take a text box and do something useful with it in a standardized way. For this example, we will change the background color of a text box as it receives the focus.
Create a form. Create three text box controls on that form. When I created them they were named Text0, Text2 and Text4.
Option Explicit’clsCtlTxtDim WithEvents mtxt As TextBox
Const cnEvProc As String = “[Event Procedure]”
Dim lngBackColor As Long ‘A place to store the original back color so it can be restored when donePrivate Sub Class_Terminate()
MsgBox “unload class for: ” & mtxt.Name
Set mtxt = Nothing
Function mInit(ltxt As TextBox)
Set mtxt = ltxt
lngBackColor = mtxt.BackColor ‘Save the back color of the control
MsgBox “Init the class for: ” & mtxt.Name
‘The text string “[Event Procedure]” placed into any event property
’causes Access to begin raising events for that event property
mtxt.OnGotFocus = cnEvProc ‘Cause Access to start raising this event
mtxt.OnLostFocus = cnEvProc ‘Cause Access to start raising this event
Private Sub mtxt_GotFocus()
mtxt.BackColor = vbCyan ‘I hard coded this to make it simple. You can use some method to pass this in
Private Sub mtxt_LostFocus()
mtxt.BackColor = lngBackColor ‘Restore the back color as we leave
Next, insert the following code into the form. If your text controls are not named Text0, Text 2 and Text4, then rename them to those names for the purposes of this demonstration.
Open the form. One of the controls will have the focus, and that text box will have a light blue background. Tab through the controls and notice that the control with the focus has a blue background.
As programmers we learned how to create event sinks in the form module, which is a class instance. Once we did that, we would perform some action when that code ran, such as changing the background color of a text box as it got the focus and setting it back to the original color as it lost the focus. This is old news.
What we’ve just learned is that we can place all of that code out into a class, and when the control’s event fires, control is passed into the event sink in the class rather than in the form’s class. Notice that there is no longer any code in the form specific to events for the text boxes. This is a fundamental lesson about classes: Objects that can raise events can have their events sunk in a class.
We have created a text box wrapper class (my terminology). We instantiated the class three times in the form, and passed in pointers to three text boxes. Inside the class, we saved a pointer to the text box in a variable dimensioned using the key word WithEvents. The WithEvents keyword tells the compiler that this class expects to sink events for the object stored in that variable — in this case, the text box.
It is important to understand that we cannot make this generic; i.e., we cannot pass in a textbox as object and store that in an object variable Withevents. The reason is simply that the object data type cannot figure out what events the object can raise and so cannot figure out what events to sink for the object. If we pass in a control of any type, it must be passed in to mInit into a variable of that specific control type. A textbox passed in to a textbox variable, a combo passed into a combo variable, etc.
Once we do that, however, and once we store the control into a variable inside of the class dimensioned with the keywordWithEvent, we can then sink any or all of the events that the control can raise. This class can, if we desire, sink the click event, AfterUpdate, KeyDown, and so forth. Any or all of the events can be sunk inside of our class.