Visio Event Objects

3 4

A Microsoft Visio Event object pairs an event with an action—either to run a Visio add-on or to notify an object in your program (also called a sink object or an event sink) that the event occurred. Your solution creates Event objects that describe the events you want to handle and tell Visio the action to take. When that event occurs, the Event object fires, triggering its action.

The first thing you must do is determine the type of Event object that your solution requires. What is your source object? What events do you need to receive? How will your solution respond to the events it does receive? Once you make these decisions, you create an Event object that runs an add-on or receives notifications.

Note


In versions of Microsoft Visual Basic and Microsoft Visual Basic for Applications (VBA) earlier than 5.0, this was the only way to create an event handler in the Visio application. If you are developing solutions in a language other than VBA, this is often the best technique. But if you are developing solutions in Visual Basic or VBA 5.0 or later, you might want to consider writing code behind events. For details about writing code behind events in Visio, see Writing Code Behind Events earlier in this chapter.

Defining Your Event Object

Before you create an Event object, you need to decide the following:

  • The scope that the Event object should fire in.
  • The event or events you want to receive.
  • The action to perform when the event occurs—run an add-on or send a notification to an object in an already running program.

Determine the scope

The scope determines the source object whose EventList collection the Event object is added to. Any object that has an EventList collection can be a source of events. For performance reasons, add the Event object to the EventList collection of the lowest object in the hierarchy that can fire the Event object in the scope you want.

Indicate the event or events that will trigger an action

To indicate the event you want to handle, supply its event code to the Add or AddAdvise method. Event codes are prefixed with visEvt in the Visio type library. In some cases, an event code is a combination of two or more codes. For example, the event code for the ShapeAdded event is visEvtAdd + visEvtShape. In some cases, you can combine codes to indicate an interest in multiple events with a single Event object. For example, the event code visEvtAdd + visEvtPage + visEvtShape indicates that you're interested in both ShapeAdded and PageAdded.

When an Event object fires, the Visio engine passes the event code for the event that actually occurred, even if the Event object's event code indicates multiple events. To continue the last example, if a page is added, the Visio engine passes the event code visEvtAdd + visEvtPage.

Note


Visual Basic and VBA report a run-time overflow error when performing statements using visEvtAdd. For example:
 Set evt = evtList.AddAdvise(visEvtAdd + visEvtShape, _ sinkObj, "", "")  

The following factors cause this overflow condition:

  • The first argument to the AddAdvise method is a 2-byte integer.
  • Because visEvtAdd is declared as a member of an enumeration in the Visio type library, it is treated as a 4-byte integer.
  • The value of visEvtAdd is &H8000.
  • Visual Basic and VBA do not support unsigned arithmetic.

Because visEvtAdd is a 4-byte value, which Visual Basic and VBA consider positive, visEvtAdd + visEvtShape is treated as 32768+64 = 32832, which is outside the range of legal values for a 2-byte signed quantity

If visEvtAdd is explicitly declared as a 2-byte quantity with the value &H8000, Visual Basic and VBA consider it to be negative, and visEvtAdd + visEvtShape is treated as "32768+64 = "32704, which is in the range of legal 2-byte signed quantities.

To declare visEvtAdd as a 2-byte value in your program, add the following statement:

 Global Const visEvtAdd% = &H8000 

Decide the action to perform

The action determines which method you use to create the Event object, Add or AddAdvise. After you've decided what the source object should be, you can create the Event object by adding it to the EventList collection of the source object.

  • To run an add-on or other external program, create an Event object using the Add method of the source object's EventList collection.
  • To send a notification, create an Event object using the AddAdvise method of the source object's EventList collection. You must also tell Visio the object to notify. This will be a reference to your event sink.

For details on the Add and AddAdvise methods, see the Microsoft Visio Developer Reference (on the Help menu, click Developer Reference).

Filtering Your Event Object

Beginning with Microsoft Visio 2002, you can use event filters to refine the events that you receive in your program. You can filter events by object, cell, ranges of cells, or command ID. Event filtering allows you to tailor the events you listen to and prevents many of the events you don't want to hear from firing.

When an Event object created with the AddAdvise method is added to the EventList collection of a source object, the default behavior is that all occurrences of that event are passed to the event sink. The methods SetFilterObjects, SetFilterSRC, and SetFilterCommands provide a way to ignore (or pay attention to) selected events. Each method specifies an array and a True or False value indicating how to filter events for an object, a cell, ranges of cells, or for a command ID. Set the value to True to listen to events, or False to exclude events.

Note


If you set a filter to listen to specific events (by object, cell, ranges of cells, or command ID), only those events will fire.

For an event to successfully pass through an object filter, a cell range filter, or a command filter, it must satisfy the following criteria:

  • It must be a valid object type, have a valid section, row, or cell reference, or have a valid command ID.
  • If all filters are True, the event must match at least one filter.
  • If all filters are False, the event must not match any filter.
  • If the filters are a mixture of True and False, the event must match at least one True filter and not match any False filters.

Methods available for implementing event filters

Method

Description

SetFilterObjects

Provides a way to ignore or listen to selected events based on object type.

One-dimensional array, 2 elements per object filter description (object type, True/False)

Valid object types to filter on include: visTypePage, visTypeGroup, visTypeShape, visTypeForeignObject visTypeGuide, and visTypeDoc.

SetFilterSRC

Provides a way to ignore or listen to selected events based on a range of one or more cells.

One-dimensional array, 7 elements per cell filter description (begin section, begin row, begin cell, end section, end row, end cell, True/False)

SetFilterCommands

Provides a way to ignore or listen to selected events based on a range of commands using command ID.

One-dimensional array, 3 elements per command filter description (begin command, end comment, True/False)

The following example shows how you might create an event sink, get and set objects, and filter events that are passed to the event sink:

 Option Base 1 Option Explicit 'Event sink Dim vEventSink As adviseMe Dim vEvent As Visio.Event Public Sub SinkEvent() 'Get and set Event objects. Dim vEventList As Visio.EventList       'Get EventList collection for the document.       Set vEventList = ActiveDocument.EventList       'Add an advise sink.       'adviseMe is a VB Class Module that implements       'IVisEventProc to process events.       Set vEventSink = New adviseMe       'Add the cell changed event to the event list.       Set vEvent = vEventList.AddAdvise(visEvtCell + visEvtMod, _             vEventSink, "", "") End Sub Public Sub SetFilter()       'Array for FilterObjects       Dim arrFilterObjects(2) As Long       'Array for FilterSRC       Const maxSRCs As Integer = 1       Dim arrFilterSRC(maxsrcs * 7) As Integer       'Array for FilterCommands       Dim arrFilterCommands(3) As Long       'Set up an array of various objects to listen to.       'Set up the FilterObject array to listen to Shape objects only.       arrFilterObjects(1) = visTypeShape       arrFilterObjects(2) = True       'Set the filter for the event.       vEvent.SetFilterObjects arrFilterObjects       'Set up the FilterSRC array for specific cells to _       'pay attention to.       'Listen to all cells in the Transform section       'using visCellInval to say any cell.       'Start cell of first range       arrFilterSRC(1) = visSectionObject       arrFilterSRC(2) = visRowXFormOut       arrFilterSRC(3) = visCellInval       'End cell of first range       arrFilterSRC(4) = visSectionObject       arrFilterSRC(5) = visRowXFormOut       arrFilterSRC(6) = visCellInval       'Receive events for the described range.       arrFilterSRC(7) = True       'Set the filter for the event.       vEvent.SetFilterSRC arrFilterSRC       'Set up the FilterCommands array to block cell       'changed events caused by the Lay Out Shapes command.       arrFilterCommands(1) = Visio.VisUICmds.visCmdToolsLayoutShapesDlg       arrFilterCommands(2) = Visio.VisUICmds.visCmdToolsLayoutShapesDlg       arrFilterCommands(3) = False       'Set the filter for the event.       vEvent.SetFilterCommands arrFilterCommands End Sub 

You can get the current status of an event filter using the methods GetFilterObjects, GetFilterSRC, GetFilterCommands.

For other details about using event filters, see the method topics prefixed with SetFilter and GetFilter in the Microsoft Visio Developer Reference (on the Help menu, click Developer Reference).

Getting Information about an Event Object

After you create an Event object, you can get information about it by querying its properties (as described in the Microsoft Visio Developer Reference). In addition, the EventInfo property of the Application object provides more information about certain events after they occur. For example, after the ShapesDeleted event fires, you can get the names of the deleted shapes from the EventInfo property.

Because there is only one EventInfo property for potentially many events, you must specify the event you want to handle when you get EventInfo. To do this, pass the event's sequence number (which Visio passes as the third argument when it calls VisEventProc on the corresponding sink object), or pass visEvtIDMostRecent for the most recent event. If there is no additional information for the event you specify, EventInfo returns an empty string.

For details about the information passed by a particular event, search for that event in the Microsoft Visio Developer Reference (on the Help menu, click Developer Reference).

Creating an Event Object that Runs an Add-on

An Event object that runs an add-on is created using the Add method of the EventList collection. To create an Event object that runs an add-on, you invoke the Add method with the following arguments:

  • The event code for the event or events that you want to handle
  • The action code visActCodeRunAddon
  • The name of the add-on to run
  • Optionally, a string of arguments to pass to the add-on when the Event object fires

When the Event object fires, Visio passes the argument string as command line arguments if the add-on is an exe file, or as the lpCmdLineArgs field of the VAOV2LSTRUCT structure passed to an add-on implemented by a Visio library ( vsl ). For example, the following code creates an Event object that runs an add-on called Showargs.exe and passes the string "/args=Shape added!" as a command line argument. The Event object is added to the EventList collection of the document.

 Private Sub Form_Load()       Dim eventsObj As Visio.EventList       Dim docObj As Visio.Document       'Create a new drawing.       'A Visio instance has already been assigned to g_appVisio.       Set docObj = g_appVisio.Documents.Add("")       'Get the EventList collection of this document.       Set eventsObj = docObj.EventList       'Add an Event object that will run an add-on when the event _       'fires.       eventsObj.Add visEvtShape + visEvtAdd, visActCodeRunAddon, _             "SHOWARGS.EXE", "/args=Shape added!" End Sub 

When a shape is added to any page in the document, the ShapeAdded event fires. The action the event triggers is to run the add-on Showargs.exe , which will identify the shape that was added along with the string "Shape added!".

Persistence of an Event Object that Runs an Add-on

An Event object that runs an add-on can be stored with a Visio document if the source object has a PersistsEvents property of True. This is sometimes called persisting an event. An Event object can be stored with a document if it meets the following conditions:

  • The Event object's action must be to run an add-on. Event objects that send notifications cannot be stored. If an Event object can be stored, its Persistable property is True.
  • The PersistsEvents property of the event's source object must be True. Beginning with Microsoft Visio 2000, Document, Page, and Master objects can do this.

Whether a persistable Event object actually persists depends on the setting of its Persistent property. If the Event object is persistable, the Visio instance assumes that it should be stored with the document, so the initial value of its Persistent property is True. If you do not want the Visio instance to store the Event object, set its Persistent property to False.

Note


Before you attempt to change an Event object's Persistent property, make sure its Persistable property is True. Setting the Persistent property of a nonpersistable event causes an error.

Creating an Event Object that Sends a Notification

An Event object that sends a notification is created using the AddAdvise method of the EventList collection and can send a notification to a program that is already running. Creating this kind of Event object differs from creating one that simply runs an add-on in the following ways:

  • You define an object in your program—not a Visio object—to receive the notification when it is sent. This kind of object is sometimes called a notification sink or sink object.
  • You write an event procedure (VisEventProc) in your sink object to handle notifications when they are received.
  • Your program creates instances of sink objects and the Event objects in the Visio instance at run time. Because this kind of Event object uses references, it cannot be stored with a Visio document and must be created each time the program runs.

The following diagram shows how a program interacts with objects in Visio to receive event notifications.

figure 21-3. the interaction between a client event sink and a visio source object.

Figure 21-3 The interaction between a client event sink and a Visio source object.

In this diagram, pSource is a reference to the source object in the Visio instance. This is used to get a reference to the source object's EventList collection, which is assigned to pEvtList.

The program uses pEvtList.AddAdvise to create the Event object, which is assigned to pEvt. With AddAdvise, the program passes a reference to the sink object that the Visio instance sends the notification to when the Event object fires.

Define the sink object to receive notifications

A sink object is a non-Visio object you define to receive the notifications that the Visio instance sends. At a minimum, the sink object must be programmable (that is, it must support the Automation IDispatch interface) and must expose an event procedure named VisEventProc. You can give the sink object whatever additional functionality makes sense for your program. You can structure your solution in many ways. For example, you can create:

  • One class for each event fired by a source object.
  • One class to capture all the events fired by a single source object.
  • One class to capture the events from multiple source objects.
  • One class to handle a certain event fired from multiple source objects.

To create a sink object in VBA or Visual Basic

  1. In your VBA project, on the Insert menu, click Class Module. Or, in your Visual Basic project, on the Project menu, click Add Class Module.
  2. Name the new object. This is your sink object.

Typically, you would set the object's Public property to True, but that isn't required. If you want, you can code predefined methods such as Initialize and Terminate or add your own methods to the class.

Note


Visual Basic projects that use the AddAdvise method must be set up as ActiveX EXE projects rather than a Standard EXE projects because they must expose public objects (sink objects). The Instancing property of classes that serve as sink objects should generally be set to MultiUse.

Write the VisEventProc event procedure

In your class module, write an event procedure called VisEventProc to handle notifications when they are received from Visio. Write code in the VisEventProc procedure in whatever way makes sense for your program. Visio does not require you to design your event handler in any particular way. You can choose to use any technique for branching within your procedure, and depending on the number and category of events your program will handle, you might define a different sink object for each event. When an Event object fires, the Visio instance calls the VisEventProc procedure for the corresponding sink object.

The VisEventProc procedure must be declared with the following parameters:

 Public Sub VisEventProc( _       'The event code of the event that caused the Event       'object to fire.       eventCode As Integer, _       'A reference to the source object whose EventList       'collection contains the Event object that fired.       sourceObj as object, _ 'The unique identifier of the Event object within its       'EventList collection. Unlike the Index property, the       'identifier does not change as objects are added or       'removed from the collection. You can access the Event       'object from within the VisEventProc procedure by using       'source.EventList.ItemFromID(id).       eventID As Long, _       'The sequence of the event relative to events that have       'fired so far in the instance of Visio.       seqNum As Long, _       'A reference to the subject of the event, which is the       'object to which the event occurred.       subjectObj As Object, _       'Additional information, if any, that accompanies the       'notification. For most events, this argument will be       'Nothing.       moreInfo As Variant) As Variant End Sub 

Note


Beginning with Microsoft Visio 2000, VisEventProc is defined as a function that returns a value. However, Visio only looks at return values from calls to VisEventProc that are passed a query event code. Sink objects that provide VisEventProc through IDispatch require no change.

To modify existing event handlers so they can handle query events, change the Sub procedure to a Function procedure and return the appropriate value. For details about query events, see the AddAdvise method and event topics prefixed with Query in the Microsoft Visio Developer Reference (on the Help menu, click Developer Reference).

Create the Event object that sends the notification

Now that your program has defined your sink object, you will need to create Event objects to include in the EventList collection of the source object whose events you want to receive.

To create an Event object that sends a notification

  1. Create an instance of your sink object.
  2. You can use the same instance of the sink object for multiple Event objects, or you can use more than one instance of the sink object.

  3. Get a reference to the EventList collection of the source object in the Visio instance.
  4. Use the AddAdvise method and provide the event code and a reference to the sink object.
  5. AddAdvise has two additional arguments. The third argument is reserved for future use and should be a null string ( "" ) . The fourth argument can be a string of arguments for the event handler. The Visio instance assigns these to the Event object's TargetArgs property. When your program receives a notification, VisEventProc can retrieve these arguments from the Event object that called it.

To define a sink object and set up event notification in your VBA or Visual Basic project

  1. Insert a class module into your project.
  2. In your class module, write an event procedure called VisEventProc.
  3. If you use the following Implements statement in your class module, you can click IVisEventProc in the Object box and then click VisEventProc in the Procedure box.

     Implements Visio.IVisEventProc 

    For details about the Implements keyword, see your Visual Basic documentation.

  4. In the VisEventProc procedure, write code to handle the notifications received from Visio in whatever way makes sense for your program.
  5. In your program, create an instance of your class module.
  6. Get a reference to the EventList collection of your source object.
  7. Use the AddAdvise method of the EventList collection to create your Event object.

The VisEventProc Procedure: an Example

The following VisEventProc procedure uses a Select Case block to check for three events: DocumentSaved, PageAdded, and ShapesDeleted. Other events fall under the default case (Case Else). Each Case block constructs a string (strDumpMsg) that contains the name and event code of the event that fired. Finally, the procedure displays the string in a message box.

 Public Sub VisEventProc(eventCode As Integer, _       sourceObj As Object, eventID As Long, seqNum As Long, _       subjectObj As Object, moreInfo As Variant) As Variant       Dim strDumpMsg As String       'Find out which event fired.       Select Case eventCode             Case visEvtCodeDocSave                   strDumpMsg = "Save(" & eventCode & ")"             Case (visEvtPage + visEvtAdd)                   strDumpMsg = "Page Added(" & eventCode & ")"             Case visEvtCodeShapeDelete                   strDumpMsg = "Shape Deleted(" & eventCode & ")"             Case Else                   strDumpMsg = "Other(" & eventCode & ")"       End Select       'Display the event name and code.       frmEventDisplay.EventText.Text = strDumpMsg End Sub 

For an example of a program that creates Event objects that might call this procedure, see Event Objects that Send Notifications: an Example later in this section.

Note


Beginning with Microsoft Visio 2000, VisEventProc is defined as a function that returns a value. However, Visio only looks at return values from calls to VisEventProc that are passed a query event code. Sink objects that provide VisEventProc through IDispatch require no change.

To modify existing event handlers so they can handle query events, change the Sub procedure to a Function procedure and return the appropriate value. For details about query events, see the AddAdvise method and event topics prefixed with Query in the Microsoft Visio Developer Reference (on the Help menu, click Developer Reference).

Event Objects that Send Notifications: an Example

For example, let's say that when we created our sink object, we called the class module that we inserted into our project CEventSamp. The following code creates an instance of the sink object CEventSamp and creates Event objects to send notifications of the following events: DocumentSaved, PageAdded, and ShapesDeleted.

 'Create an instance of the sink object class CEventSamp. Dim g_Sink As CEventSamp Dim docObj As Visio.Document Private Sub Form_Load()       Dim eventsObj As Visio.EventList       'Create an instance of the CEventSamp class.       'g_Sink is global to the form.       Set g_Sink = New CeventSamp       'Create a new drawing.       'A Visio instance has already been assigned to g_appVisio.       Set docObj = g_appVisio.Documents.Add("")       'Get the EventList collection of this document.       Set eventsObj = docObj.EventList       'Add Event objects that will send notifications.       'Add an Event object for the DocumentSaved event.       eventsObj.AddAdvise visEvtCodeDocSave, g_Sink, "", "Document Saved..."       'Add an Event object for the ShapesDeleted event.       eventsObj.AddAdvise visEvtCodeShapeDelete, g_Sink, "", "Shape Deleted..."       'Add an Event object for the PageAdded event       eventsObj.AddAdvise (visEvtPage + visEvtAdd), g_Sink, "", "Page Added..." End Sub 

When the PageAdded, ShapesDeleted, or DocumentSaved event fires, the Visio instance calls VisEventProc on the sink object g_sink. For an example of acorresponding VisEventProc procedure, see The VisEventProc Procedure: an Example earlier in this section.

Lifetime of an Event Object that Sends a Notification

Event objects created with the AddAdvise method persist until:

  • The Event object is deleted with the Delete method.
  • All references to the source object are released, including references that are held indirectly through a reference to the source object's EventList collection or to an Event object in the collection.
  • The Visio instance terminates.

When the Visio instance terminates, it issues a BeforeQuit event, which the program should handle by releasing all its references to source objects or performing any other cleanup tasks. After the Visio instance issues BeforeQuit, it releases all its references to sink objects in the program.



Developing Microsoft Visio Solutions 2001
Developing Microsoft Visio Solutions (Pro-Documentation)
ISBN: 0735613532
EAN: 2147483647
Year: 2004
Pages: 180

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net