Friday, November 11, 2011

Writing Code to Respond to Events


Writing Code to Respond to Events

Outlook macros are very useful for simple repetitive tasks. However, macros are only a snack compared with the banquet of events available in the Outlook 2002 Object Model. For Visual Basic developers, the key to writing code that responds to events is learning how to use the WithEvents keyword in Visual Basic.

Use the WithEvents Keyword to Declare Object Variables

The WithEvents keyword is used to dimension an object variable in a class module. If you attempt to use WithEvents in conjunction with an object declaration in a standard module, your code will raise an error and will not compile. By declaring an object using WithEvents, you notify Visual Basic that you want to respond to events for the instance that is assigned to that object variable. You can use the WithEvents keyword only with objects that support events, and only in a class module such as ThisOutlookSession.
If you want to use C++ to write code supporting the new events in Outlook 2002, you should see the Microsoft Product Support Services sample COM Add-in at http://support.microsoft.com/support/kb/articles/Q230/6/89.ASP. It comes with an Office COM Add-in template for Visual C++ that you can use to develop Outlook COM Add-ins in C++, should you so desire. This template contains complete instructions for implementing the IDTExtensibility2 interface in Microsoft C++ Version 6.
Because the class module ThisOutlookSession represents the Outlook Application object, you do not have to explicitly declare an Outlook Application object using the WithEvents keyword when you write Outlook VBA code. If you examine the code window for ThisOutlookSession, you’ll notice that all the events for the Outlook Application object are available in the Procedures drop-down list box. Figure 9-6 shows the Application object in the code window for ThisOutlookSession.
Figure 9.6 - Select an Application event from the Procedures drop-down list box to create an application-level event procedure.

When You Must Use WithEvents to Declare the Outlook Application Object

If you are writing a COM Add-in that traps Outlook events, you must explicitly declare an Outlook Application object using the WithEvents keyword. COM Add-ins are beyond the scope of this chapter; they are discussed in depth in Chapter 14. The technique you should use to create child objects of the Application object, however, applies equally to COM Add-ins and Outlook VBA code. Many of the child objects of the Application object can also raise events. You might be wondering how you write event procedures for those child objects. The trick is to declare these objects using the WithEvents keyword and to instantiate those objects in the correct event procedures. Object-related events beget additional event-aware objects and their event procedures.

Using WithEvents for Child Objects

As discussed previously, all objects in the Outlook Object Model are child objects of the parent Application object. Not every Outlook object supports events. Consult the Object Browser in Outlook VBA or the Microsoft Outlook Visual Basic Reference Help to determine which Outlook objects raise events. The following table lists application-level events in Outlook 2002 and the objects that raise those events. The events and objects that are new to Outlook 2002 appear in bold. Note that certain events are cancelable, meaning that you can write code to roll back the event depending on the conditions you evaluate during event processing.
ObjectEventCancelable
Application
AdvancedSearchComplete AdvancedSearchStopped
ItemSend
MapiLogonComplete
NewMail
OptionsPagesAdd
Quit
Reminder
Startup
No
No
Yes
No
No
No
No
No
No
NameSpace
OptionsPagesAdd
No
Explorers
NewExplorer
No
Explorer
Activate
BeforeFolderSwitch
BeforeItemCopy
BeforeItemCut
BeforeMaximize
BeforeMinimize
BeforeMove
BeforeSize
BeforeViewSwitch
Close
Deactivate
FolderSwitch
SelectionChange
ViewSwitch
No
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
No
No
No
No
No
SyncObject
OnError
Progress
SyncEnd
SyncStart
No
No
No
No
OutlookBarPane
BeforeGroupSwitch
BeforeNavigate
Yes
Yes
OutlookBarGroup
GroupAdd Before
GroupAdd Before
GroupRemove
No
Yes
Yes
OutlookBarShortcut
ShortcutAdd Before
ShortcutAdd Before
ShortcutRemove
No
Yes
Yes
Folders
FolderAdd
FolderChange
FolderRemove
No
No
No
Inspectors
NewInspector
No
Inspector
Activate
BeforeMaximize
BeforeMinimize
BeforeMove
BeforeSize
Close
Deactivate
No
Yes
Yes
Yes
Yes
No
No
Items
ItemAdd
ItemChange
ItemRemove
No
No
No
Reminders
BeforeReminderShow
ReminderAdd
ReminderChange
ReminderFire
ReminderRemove
Snooze
Yes
No
No
No
No
No
Views
ViewAdd
ViewRemove
No
No
To raise events for these child objects, you should follow these coding practices:
  • Dimension the object as a public object variable, and use the WithEvents keyword in a class module. If you’re writing Outlook VBA code, declare the child object variables using WithEvents in ThisOutlookSession.
  • Instantiate the child object variable in an appropriate event procedure, or use a Sub procedure in module-level code to instantiate object variables that raise events. For example, you should instantiate the NameSpace object and the Explorers and Inspectors collection objects in the Application Startup event so that the events supported by these objects will be available throughout the life of the application. The following code illustrates this technique:
‘Place these declarations in ThisOutlookSession
Public WithEvents objNS As Outlook.NameSpace

Public WithEvents colReminders As Outlook.Reminders
Public WithEvents colViews as Outlook.Views
Public WithEvents colFolders As Outlook.Folders
Public WithEvents objExpl As Outlook.Explorer
Public WithEvents colExpl As Outlook.Explorers
Public WithEvents objInsp As Outlook.Inspector
Public WithEvents colInsp As Outlook.Inspectors
Public WithEvents colInboxItems As Outlook.Items
Public WithEvents colDeletedItems As Outlook.Items

Private Sub Application_Startup()
    Set objNS = Application.GetNamespace("MAPI")
    Set colFolders = objNS.Folders
    Set colReminders = Application.Reminders
    Set colExpl = Application.Explorers
    Set colInsp = Application.Inspectors
    Set objExpl = Application.ActiveExplorer
    Set colViews = objExpl.CurrentFolder.Views
    Set colInboxItems = objNS.GetDefaultFolder(olFolderInbox).Items
    Set colDeletedItems = _
      objNS.GetDefaultFolder(olFolderDeletedItems).Items
End Sub

Where to Instantiate Child Objects Declared Using WithEvents

It’s important to determine the correct event procedure when you create additional child objects. For example, if you want to raise events for an Explorer object, you can either set a reference to an Explorer object in the Application Startup event or you can use the NewExplorer event of the Explorers collection object. The NewExplorer event passes an Explorer object to the NewExplorer event procedure. Using the code example above, a reference is set to objExpl in the Application Startup event. This Explorer object refers to the ActiveExplorer object of the Application object when Outlook launches. Either users or code can cause multiple Explorer objects to display for a given Outlook Application object. If you want to trap events such as FolderSwitch or BeforeShortcutAdd for another instance of an Explorer, you must either create a new Explorer object that you can instantiate in the NewExplorer event or reuse the existing objExplobject and set objExpl to the Explorer object that you receive in the NewExplorer event. Many of the examples in the following section will discuss strategies and options for raising events on child objects of the application’s parent object.

Observing Events in the Example VBAProject.otm

Because it writes a statement to the VBA Immediate window when an event procedure fires, the VBAProject.otm project accompanying this book lets you observe events for mostof the available events in the Outlook Object Model. Following the firing sequence of events in the Immediate window is an excellent way to learn about the new events in the Outlook Object Model. To observe event tracing in the VBA Immediate window, you must follow these steps:

To turn on event tracing in the VBAProject.otm example

  1. Select Macro from the Tools menu.
  2. Select Security from the Macro submenu.
  3. On the Security Level page of the Security dialog box, click the Low option. If you click Medium, you will have to click Enable Macros in the Security Warning dialog box every time Outlook starts.
  4. Click OK.
  5. Press Alt+F11 to open the VBA Editor.
  6. Select Project1 Properties from the Tools menu.
  7. In the Conditional Compilation Arguments edit box on the General page of the Project 1 – Project Properties dialog box, enter conDebug = 1.
  8. Click OK.
  9. Press Alt+F11 to return to Outlook.
  10. Select Exit And Log Off from the File menu.
  11. Restart Outlook. Event tracing will be turned on, and you can observe the firing sequence of events in the VBA Immediate window.

No comments:

Post a Comment