There are some terms that we will need to learn in order to get a handle on WithEvents , and be able to discuss event handling among ourselves . As you know, objects can cause events to happen. This process is called sourcing an event. One thing that may not be obvious is that an event acts very similar to a radio broadcast of a message. The following is a simplified version of what really happens.
An event occurs, which could be the click of a mouse. Windows takes that click and determines what program of all those currently running "owned" the piece of screen that the click occurred on, and notifies that program (Access in this case) that the click occurred, passing in a "handle to window" of the object clicked on. That program (for our purposes Access, but also Word or Excel, or almost any other Windows program) discovers which of its controls corresponds to that "handle to window" and notifies that control that the mouse clicked on it. Everything that happens from the click to the instant the event is broadcast is irrelevant to us. What we care about is that the control "broadcasts" its click event! And by broadcast we do mean broadcast. Any class inside of Access can ( potentially ) hear the event. It is important to understand the concept of an event being broadcast because it is possible (and even common) to handle an event in more than one class.
The process of "listening" or receiving program control from an object event is called sinking the event. Only classes can sink events. This is the really weird part of this whole "secret" thing - only classes can sink events, and only the WithEvents keyword allows a non-form class to sink events. (And the WithEvents keyword isn't explained anywhere in all of Access documentation!) Form classes don't need the WithEvents keyword to sink events for objects physically placed on the form, but they will need to use the WithEvents keyword to sink events generated by any objects that cannot be physically placed on the form, such as DLLs, OCXs, and classes that can be directly referenced.
Up to this point, the only place you have handled events has been in the module of a form. It turns out that form modules are classes, and the event handlers that we create in these classes are also called event sinks . So an object sources events, and a class sinks events. An event handler and an event sink are just different terms for the same thing. As an interesting aside, the terms source and sink come from electronics where transistors source and sink current.
By the way, a class is an object, and as such it too can source an event! Yes, your own classes can raise (source) events that other classes in your application can sink. That is powerful stuff as we will see towards the end of this chapter.
But first let's review a little of what we already know. A combo on a form has many possible events that it can source; Click , GotFocus , AfterUpdate , and so on. Back in Chapter 3 we learned how to use the property box of a control to select an event property, then click the builder button (the ellipsis to the right of the property) and select code builder. This caused Access to do two things. First of all it built an event handler shell sub for us in the form's module. The empty event handler shell is also known as an event stub . It is called a stub because it contains only the Sub and End Sub lines with no real code inside of it. It also placed the text [Event Procedure] in the event property of the property sheet.
Having created the event stub, we can now place code into the sub that the code builder built for us. When that event fires for that object, program control is transferred to the event handler sub and our code begins to run.
An interesting and little known fact is that it is the very existence of the text [Event Procedure] in the object's event property that causes (or allows) Visual Basic to allow the event to fire. We can literally turn off the broadcasting of an individual event simply by deleting that [Event Procedure] text in the event property, and turn it back on by setting [Event Procedure] back in the property. Even if you have an event stub for a combo's click event (for example) in the form's module, simply delete the [Event Procedure] in the combo's Click event property and the event will never fire (source the event). As the event never even fires, the click event code will never run. Put [Event Procedure] back in the property and the event starts firing again. We will be using this little known fact to turn on an object's event broadcasting from right inside our classes from code in our class's Init event.