Handling Visio Events in C++ Programs
One way to handle Microsoft® Visio® events in a C++ program is to use Event objects. An Event object pairs an event code with an action—either to run an add-on or to notify another object, called a sink object, whenever the specified event has occurred. For a discussion of how Event objects work and details about implementing them in Microsoft® Visual Basic® programs, see Chapter 21, Handling Visio Events.
The protocols the Visio engine uses to support the Visual Basic WithEvents style of event handling are the standard IConnectionPoint protocols provided by controls and used by control containers. As an alternative to using Event objects, a C++ program can receive events from a Visio instance using IConnectionPoint protocols, but it must implement the entire event-set interface declared for the type of Visio object from which it wants to receive events. For details about IConnectionPoint and related interfaces, see your Component Object Model (COM) documentation.
The topics in this section describe how to receive Visio events in C++ programs using Event objects that are established by calling EventList.Add or EventList.AddAdvise. Although this protocol is specific to Visio, a C++ program need not implement entire event-set interfaces; instead, the C++ program can register for just the events of interest rather than every event in an event set, which IConnectionPoint requires.
In this section...
Implementing a Sink Object
Using CVisioAddonSink
Implementing a Sink Object
You implement handling of Visio events in a C++ program in much the same way as in a Visual Basic program, with these exceptions:
- The sink object in your C++ program must be a COM object that exposes the IDispatch interface.
- The IDispatch interface must supply a method called VisEventProc that has the following signature:
|
|
|
When you call AddAdvise to create the Event object, you pass a pointer to the IUnknown or IDispatch interface on the sink object.
Using CVisioAddonSink
Beginning with Microsoft Visio 2000, instead of implementing your own sink object, you can use the CVisioAddonSink class provided with the Microsoft Visio 2002 SDK. This class is declared in the file Addsink.h, which is installed with the Visio SDK.
To use CVisioAddonSink
- Include Addsink.h in your project source files. If you're using the wrapper classes defined in Visiwrap.h, skip this step.
- Write a callback function to receive the event notifications sent to the sink object.
- Call CoCreateAddonSink with a pointer to your callback function and the address of an IUnknown interface. CoCreateAddonSink creates an instance of a sink object that knows about your callback function and writes a pointer to an IUnknown interface on the sink object to the address you supplied.
- Get a reference to the EventList collection of the Visio object that you want to receive notifications from.
- Call the AddAdvise method of the EventList collection, obtained in step 4, with the IUnknown interface, obtained in step 3, and the event code of the Visio event that you're interested in. When the event occurs, the Visio instance will call your callback function.
- Release the sink object when you're finished using it.
The sample program Generic.cpp uses CVisioAddonSink to handle two events: DocumentCreated and ShapeAdded. The program declares a callback function for each event. The signature of the callback function must conform to visEventProc, which is defined in Addsink.h. The following example shows one of the declarations. For the implementation of this function, see Generic.cpp.
HRESULT STDMETHODCALLTYPE ReceiveNotifyFromVisio (
|
|
To create the sink object, the program gets the EventList collection of the Application object (represented by the CVisioApplication variable app), calls CoCreateAddonSink to create the sink object, and calls AddAdvise on the EventList collection to create the Event object in the Visio instance. The program sets a flag, bFirstTime, to ensure that the Event objects are created only once while the program is running. The ID of the Event object is stored in the static variable stc_nEventID for later reference. The AddAdvise call creates a second reference on the sink object, so the program can release pSink:
|
|
if (bFirstTime && (SUCCEEDED(app.EventList(eList)))) { bFirstTime= FALSE; if (SUCCEEDED(CoCreateAddonSink(ReceiveNotifyFromVisio, &pSink))) { if (SUCCEEDED(eList.AddAdvise(visEvtCodeDocCreate, VVariant(pSink), VBstr(""), VBstr(""), event))) { event.ID(&stc_nEventID); } //If AddAdvise succeeded, Visio now holds a reference to the sink object //via the event object, and pSink can be released pSink->Release(); pSink= NULL; } ... }
Event objects created with AddAdvise persist until the Event object is deleted, all references to the source object are released, or the Visio instance is closed. If your program needs to perform cleanup tasks before the Visio instance is closed, handle the BeforeQuit event.
If CVisioAddonSink is used in a Visio library (VSL), its unload handler must call Event.Delete.
For more information on Visio methods, events, and objects, see the Microsoft Visio Developer Reference (on the Help menu, click Developer Reference).