One of the most interesting uses for out-of-process components is to provide asynchronous notifications to the client. That is, the client doesn’t remain blocked while the component executes a method — instead, it goes about its business while the component works on a task or watches for an occurrence of interest. The component’s notification arrives out of the blue, without any specific action on the part of the client.
The procedure in this topic sets up a simple asynchronous notification based on a common data processing problem: How do you know when the coffee is ready?
The demonstration assumes that you have a coffee maker with a serial interface (however, the demonstration will work even if you don’t). The Coffee component tests the serial port periodically to see if the coffee maker’s High bit is set, indicating that the coffee is ready.
Before you begin this procedure, make sure you’ve returned the Coffee project to design mode, as described at the end of "How Modal and Modeless Forms Behave Out of Process."
Note This topic is part of a series that walks you through creating a sample ActiveX EXE. It begins with the topic Creating an ActiveX EXE Component.
To set up an asynchronous notification event in the CoffeeMonitor class
Object | Property | Setting |
Timer control | (Name) Enabled Interval |
tmrCoffee True 10000 |
There’s no need to put code in the tmrControl_Timer event procedure. As you’ll see, CoffeeMonitor will handle the control’s Timer event, test the serial port, and raise the CoffeeReady event to notify CoffeeWatch.
In order to view all the code at once, make sure you’ve selected Full Module View, as shown by the buttons in the lower left-hand corner of the code window.
You can show the Edit toolbar using the context menu accessed by right-clicking the menu or standard toolbar, as shown here:
Option Explicit
Private mTestForm As TestForm
Private WithEvents mwtmrCoffee As Timer
Event CoffeeReady()
mTestForm
will hold a reference to an instance of TestForm, whose only purpose is to hold the Timer control.mwtmrCoffee
will hold a reference to the Timer control on the TestForm. The variable is declared WithEvents so that the CoffeeMonitor object can handle the timer’s events.Private Sub Class_Initialize()
Set mTestForm = New TestForm
Load mTestForm
Set mwtmrCoffee = mTestForm.tmrCoffee
End Sub
After the instance of TestForm is created and loaded, a reference to tmrCoffee
is placed in the variable mwtmrCoffee
. When the reference is placed in the WithEvents variable, Visual Basic connects the timer’s events to the associated event procedures in CoffeeMonitor.
Private Sub Class_Terminate()
Set mwtmrCoffee = Nothing
Unload mTestForm
Set mTestForm = Nothing
End Sub
As we saw in "How Modal and Modeless Forms Behave Out of Process," objects that use forms in out-of-process components need to dispose of the forms when they’re done with them. The first step is to set the WithEvents variable to Nothing, so that CoffeeMonitor will stop handling the Timer control’s events. Then TestForm can be unloaded, and the variable containing the reference to it can be set to Nothing.
Note Strictly speaking, there’s no need to set mTestForm
to Nothing here. Visual Basic will set the variable to Nothing when it destroys the CoffeeMonitor object.
Private Sub mwtmrCoffee_Timer()
' (Code to test serial port omitted.)
RaiseEvent CoffeeReady
End Sub
Event procedures associated with a WithEvents variable always begin with the variable name, as discussed in "Adding Events to Classes" in "General Principles of Component Design."
When the CoffeeMonitor object receives the Timer event, it raises its own CoffeeReady event to notify any clients (CoffeeWatch, in this case) that the coffee’s ready.
(This code simply raises the CoffeeReady event every ten seconds. If you actually have a coffee pot with a serial port, you can add code to test coffee maker’s status, and conditionally raise the event.)
Note One of the advantages of using events to provide notifications is that only one reference is needed. That is, TestForm doesn’t need a reference to the CoffeeMonitor object in order for the Timer control to send CoffeeMonitor an event. This avoids the circular reference problem described in "Dealing with Circular References" in "General Principles of Component Design."
Component projects should be run with CTRL+F5 (or Start with Full Compile on the Run menu) if Compile On Demand is checked, as discussed in "Showing Forms from the CoffeeMonitor Class."
For More Information Events are introduced in "Adding an Event to a Class" and "Adding Events to Forms," in "Programming with Objects" in the Visual Basic Programmer’s Guide.
This topic is part of a series that walks you through creating a sample ActiveX EXE.
To | See |
Go to the next step | Receiving an Asynchronous Notification Event |
Start from the beginning | Creating an ActiveX EXE Component |