Outlook has many events that occur at the Outlook item level. We refer to Item events in this section, but there is no Item object per se in the Outlook object model. Instead, you will find Item events on each of the 16 Outlook object model objects listed in Table 10.1 Item Addition, Deletion, and Change Events Several events are raised when Outlook items are added, deleted, or changed: Items.ItemRemove is raised when an item is deleted from the Items collection associated with a folderfor example, when an item is deleted from the collection of items in the Inbox folder. It is raised once for each item removed from the collection. Unfortunately, the item removed from the collection is not passed as a parameter to this event and is difficult to determine unless you store the previous state of the items in the folder in some way. This event is also not raised if more than 16 items are deleted at once or when the last item in a folder is deleted if the folder is in a PST file. You can work around these limitations by using the FolderChange event described in the "Folder Change Events" section earlier in this chapter. For example, you could store the number of items in the folder in a variable and when handling the FolderChange event determine whether the number of items in the folder have decreased. Items.ItemChange is raised when an item is changed in the Items collection associated with a folderfor example, when an item is changed in the collection of Outlook items in the Inbox folder. Outlook passes the Outlook item that has changed as an Object parameter to this event. Items.ItemAdd is raised when an item is added to the Items collection associated with a folderfor example, when an item is added to the collection of Outlook items in the Inbox folder. It is raised once for each item that is added to the collection. Outlook passes the Outlook item that was added as an Object parameter to this event. Unfortunately, this event is not raised if a large number of items are added at once. You can work around this limitation by using the FolderChange event described in the "Folder Change Events" section earlier in this chapter. You could store the state of the items in the folder that you want to monitor for changes and, when handling the FolderChange event, determine whether the new state of the items in the folder matches the state you have stored. Item.BeforeDelete is raised on an Outlook item when the item is deleted. The item must be deleted from an Inspector window, however; the event is not raised if you just delete the item from a folder. Outlook passes by reference a Boolean cancel parameter. The cancel parameter can be set to TRue by your event handler to prevent Outlook from deleting the item. Listing 10.5 shows some VSTO Outlook add-in code that handles these events. To get to an individual MailItem to handle the Item.BeforeDelete event, the code first gets the NameSpace object. The NameSpace object is accessed by calling the Application.Session property. The NameSpace object has a method called GetDefaultFolder that returns a MAPIFolder to which you can pass a member of the enumeration OlDefaultFolders to get a standard Outlook folder. In Listing 10.5, we pass olFolderInbox to get a MAPIFolder for the Inbox. Then we use the Items collection associated with the Inbox's MAPIFolder to connect our event handlers to, as well as to get an individual MailItem to handle the Item.BeforeDelete event. Listing 10.5. A VSTO AddIn That Handles Item Addition, Change, and Delete Events Public Class ThisApplication Private WithEvents mailItem As Outlook.MailItem Private WithEvents items As Outlook.Items Private Sub ThisApplication_Startup(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Startup Dim ns As Outlook.NameSpace = Me.Session Dim inbox As Outlook.MAPIFolder = _ ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) For Each o As Object In inbox.Items If TypeOf o Is Outlook.MailItem Then mailItem = o Else Exit For End If Next If mailItem Is Nothing Then MessageBox.Show("Couldn't find a mail item to connect to.") Else AddHandler mailItem.BeforeDelete, _ AddressOf MailItem_BeforeDelete MsgBox(String.Format( _ "Connected to the mail item with subject {0}.", _ mailItem.Subject)) End If items = inbox.Items End Sub Private Sub MailItem_BeforeDelete(ByVal item As Object, _ ByRef cancel As Boolean) MsgBox(String.Format( _ "The mail item {0} cannot be deleted.", _ mailItem.Subject)) cancel = True End Sub Private Sub Items_ItemRemove() Handles items.ItemRemove MsgBox("An item is about to be removed.") End Sub Private Sub GenerateItemMessage(ByVal item As Object, _ ByVal operation As String) If TypeOf item Is Outlook.MailItem Then Dim mailItem As Outlook.MailItem = item MsgBox(String.Format( _ "MailItem {0} was just {1}.", _ mailItem.Subject, operation)) Else MsgBox(String.Format( _ "An Outlook item was just {0}.", operation)) End If End Sub Private Sub Items_ItemChange(ByVal item As Object) _ Handles items.ItemChange GenerateItemMessage(item, "changed") End Sub Private Sub Items_ItemAdd(ByVal item As Object) _ Handles items.ItemAdd GenerateItemMessage(item, "added") End Sub End Class | Copy, Paste, Cut, and Delete Events Outlook raises several events when Outlook items are copied, cut, or pasted. These events are raised on an Explorer object. An Explorer object has a Selection property that returns the current selected items in the Explorer. Because many of the Explorer events telling you that a copy, cut, or paste is about to occur do not pass the items that are being acted upon, you must examine the Selection object to determine the items that are being acted upon: Explorer.BeforeItemCopy is raised before one or more Outlook items are copied. Outlook passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item or items from being copied. Explorer.BeforeItemCut is raised before one or more Outlook items are cut. Outlook passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item or items from being cut. Explorer.BeforeItemPaste is raised before one or more Outlook items are pasted. Outlook passes a clipboardContent parameter as an Object. If the clipboard contains Outlook items that have been cut or copied, you can cast the clipboardContent parameter to a Selection object and examine what is about to be pasted. Next, Outlook passes a target parameter of type MAPIFolder. This represents the destination folder to which the item or items will be pasted. Outlook also passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item or items from being pasted. Listing 10.6 shows a VSTO Outlook add-in that handles these events. It uses a helper function called GenerateItemsMessage that iterates over the items in a Selection object and displays a dialog box with the subject of each MailItem selected. Listing 10.6. A VSTO AddIn That Handles Copy, Cut, and Paste Events Public Class ThisApplication Private WithEvents explorer As Outlook.Explorer Private Sub ThisApplication_Startup(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Startup explorer = Me.ActiveExplorer End Sub Private Sub GenerateItemsMessage( _ ByVal selection As Outlook.Selection, _ ByVal operation As String) Dim b As New System.Text.StringBuilder() b.AppendFormat("Items to be {0}:" & vbCrLf & _ vbCrLf, operation) For Each o As Object In selection If TypeOf o Is Outlook.MailItem Then Dim mi As Outlook.MailItem = o b.AppendFormat("MailItem: {0}" & vbCrLf, mi.Subject) Else b.AppendLine("Other Outlook item") End If Next MsgBox(b.ToString()) End Sub Private Sub Explorer_BeforeItemCopy(ByRef cancel As Boolean) _ Handles explorer.BeforeItemCopy GenerateItemsMessage(explorer.Selection, "copied") End Sub Private Sub Explorer_BeforeItemCut(ByRef cancel As Boolean) _ Handles explorer.BeforeItemCut GenerateItemsMessage(explorer.Selection, "cut") End Sub Private Sub Explorer_BeforeItemPaste( _ ByRef clipboardContent As Object, _ ByVal target As Outlook.MAPIFolder, _ ByRef cancel As Boolean) _ Handles explorer.BeforeItemPaste If TypeOf clipboardContent Is Outlook.Selection Then Dim selection As Outlook.Selection = clipboardContent GenerateItemsMessage(selection, "pasted") Else MsgBox("The clipboard is not a Selection object.") End If End Sub End Class | Property Change Events A typical Outlook item has many associated properties, such as CreationTime, Importance, and LastModificationTime. All the properties associated with an Outlook item are contained by the ItemProperties property. When any of these properties is changed, Outlook raises the PropertyChange event. It is also possible to define additional custom properties and associate them with an Outlook item. When custom properties are changed, Outlook raises the CustomPropertyChange event: Item.PropertyChange is raised when a property of an Outlook item is changed. Outlook passes a name parameter as a String that represents the name of the property that was changed. Item.CustomPropertyChange is raised when a userdefined property of an Outlook item is changed. Outlook passes a name parameter as a String that represents the name of the userdefined property that was changed. Open, Read, Write, and Close Events Outlook raises events when an Outlook item is opened, written to, or closed: Item.Read is raised when an Outlook item is displayed from within either an Explorer or Inspector view. This event has nothing to do with the Read or Unread status of an itemjust whether it is being displayed in a view. Item.Open is raised when an Outlook item is opened in an Inspector view. Outlook passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item from being opened. Item.Write is raised when an Outlook item is saved after being modified. Outlook passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item or items from being written to. Item.Close is raised when an Outlook item is closed after being opened in an Inspector view. Outlook passes by reference a Boolean cancel parameter. The cancel parameter can be set to TRue by your event handler to prevent the item or items from being closed. Note Close is the name of both a method and an event on Outlook item objects. Because of this collision, you will have to use the CType operator to cast the Outlook item object to the Item Events_10_Event interface when adding an event handler dynamically using the AddHandler statement. If you are adding an event handler declaratively using WithEvents and Handles, you do not have to worry about this issue. Listing 10.7 shows a VSTO Outlook add-in that handles these events. Listing 10.7. A VSTO AddIn That Handles Open, Read, Write, and Close Events Public Class ThisApplication Private mailItem As Outlook.MailItem Private Sub ThisApplication_Startup(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Startup Dim ns As Outlook.NameSpace = Me.Session Dim inbox As Outlook.MAPIFolder = ns.GetDefaultFolder( _ Outlook.OlDefaultFolders.olFolderInbox) For Each o As Object In inbox.Items If TypeOf o Is Outlook.MailItem Then mailItem = o Else Exit For End If Next If mailItem Is Nothing Then MsgBox("Couldn't find a mail item to connect to.") Else MsgBox(String.Format( _ "Connected to the mail item with subject {0}.", _ mailItem.Subject)) AddHandler mailItem.Read, AddressOf MailItem_Read AddHandler mailItem.Open, AddressOf MailItem_Open AddHandler mailItem.Write, AddressOf MailItem_Write AddHandler CType(mailItem, _ Outlook.ItemEvents_10_Event).Close, _ AddressOf MailItem_Close End If End Sub Private Sub MailItem_Read() MsgBox("Read") End Sub Private Sub MailItem_Open(ByRef cancel As Boolean) MsgBox("Open") End Sub Private Sub MailItem_Write(ByRef cancel As Boolean) MsgBox("Write") End Sub Private Sub MailItem_Close(ByRef cancel As Boolean) MsgBox("Close") End Sub End Class | EMail Events Outlook raises several emailrelated events when new mail is received, when an Outlook item is sent by email, or when an Outlook item is forwarded or replied to: Application.NewMail is raised when new items are received in the Inbox, including mail messages, meeting requests, and task requests. Application.NewMailEx is raised when new items are received in the Inbox, including mail messages, meeting requests, and task requests. An entry IDs parameter is passed as a String. The enTRyIDs parameter contains a commadelimited list of the entry IDs of the Outlook items that were received. An entry ID uniquely identifies an Outlook item. Application.ItemSend is raised when an Outlook item is sentfor example, when the user has an Outlook item open in an Inspector window and clicks the Send button. An item parameter is passed as an Object that contains the Outlook item being sent. Outlook also passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item from being sent. Item.Send is raised when an Outlook item is sentfor example, when the user has an Outlook item open in an Inspector window and clicks the Send button. Outlook passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item from being sent. Item.Reply is raised when an Outlook item is replied to. A response parameter is passed as an Object and represents the Outlook item that was created as a response to the original Outlook item. Outlook also passes by reference a Boolean cancel parameter. The cancel parameter can be set to true by your event handler to prevent the item from being replied to. Item.ReplyAll is raised when an Outlook item is replied to using the Reply All button. A response parameter is passed as an Object and represents the Outlook item that was created as a response to the original Outlook item. Outlook also passes by reference a Boolean cancel parameter. The cancel parameter can be set to TRue by your event handler to prevent the item from being replied to. Item.Forward is raised when an Outlook item is forwarded. A response parameter is passed as an Object and represents the Outlook item that was created to forward the original Outlook item. Outlook also passes by reference a Boolean cancel parameter. The cancel parameter can be set to TRue by your event handler to prevent the item from being forwarded. Listing 10.8 shows a VSTO Outlook add-in that handles these events. Listing 10.8. A VSTO AddIn That Handles EMail Events Public Class ThisApplication Private mailItem As Outlook.MailItem Private Sub ThisApplication_Startup(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Startup Dim ns As Outlook.NameSpace = Me.Session Dim inbox As Outlook.MAPIFolder = ns.GetDefaultFolder( _ Outlook.OlDefaultFolders.olFolderInbox) For Each o As Object In inbox.Items If TypeOf o Is Outlook.MailItem Then mailItem = o Else Exit For End If Next If mailItem Is Nothing Then MsgBox("Couldn't find a mail item.") Else MsgBox(String.Format( _ "Connected to the mail item {0}.", _ mailItem.Subject)) AddHandler mailItem.Send, AddressOf MailItem_Send AddHandler mailItem.Reply, AddressOf MailItem_Reply AddHandler mailItem.ReplyAll, AddressOf MailItem_ReplyAll AddHandler mailItem.Forward, AddressOf MailItem_Forward End If End Sub Private Sub GenerateItemMessage(ByVal item As Object, _ ByVal operation As String) If TypeOf item Is Outlook.MailItem Then Dim mi As Outlook.MailItem = item MsgBox(String.Format( _ "MailItem {0} will be {1}.", _ mi.Subject, operation)) Else MsgBox(String.Format( _ "An Outlook item will be {0}.", _ operation)) End If End Sub Private Sub ThisApplication_NewMail() Handles Me.NewMail MsgBox("New mail was received") End Sub Private Sub ThisApplication_NewMailEx( _ ByVal entryIDCollection As String) Handles Me.NewMailEx MsgBox(String.Format( _ "NewMailEx: {0}.", _ entryIDCollection)) End Sub Private Sub ThisApplication_ItemSend(ByVal item As Object, _ ByRef cancel As Boolean) Handles Me.ItemSend GenerateItemMessage(item, "sent") End Sub Private Sub MailItem_Send(ByRef cancel As Boolean) MsgBox("MailItem Send") End Sub Private Sub MailItem_Reply(ByVal response As Object, _ ByRef cancel As Boolean) GenerateItemMessage(response, "generated as a reply") End Sub Private Sub MailItem_ReplyAll(ByVal response As Object, _ ByRef cancel As Boolean) GenerateItemMessage(response, "generated as a reply to all") End Sub Private Sub MailItem_Forward(ByVal forward As Object, _ ByRef cancel As Boolean) GenerateItemMessage(forward, "generated as a forward") End Sub End Class | Attachment Events Outlook raises events when attachments are added to an Outlook item and when attachments associated with an Outlook item are read or saved: Item.AttachmentAdd is raised when an attachment is added to an Outlook item. Outlook passes an attachment parameter that represents the attachment that was added. Item.AttachmentRead is raised when an attachment attached to an Outlook item is opened for reading. Outlook passes an attachment parameter that represents the attachment that was read. Item.BeforeAttachmentSave is raised when an attachment attached to an Outlook item is about to be saved. Outlook passes an attachment parameter that represents the attachment that is about to be saved. Outlook also passes by reference a Boolean cancel parameter. The cancel parameter can be set to TRue by your event handler to prevent the attachment from being saved. Custom Action Events Outlook enables you to associate custom actions with an Outlook item. A custom action is given a name and some default behavior. You can create a custom action whose default behavior is to act on the original item or to create a new reply to the existing item, for example. You can also set whether the action is shown as a button, a menu command, or both. When the custom action is invoked from the menu or toolbar, the CustomAction event is raised on the associated Outlook item. Figure 10.2 shows a custom action that has been associated with an Outlook mail item called "My custom action." Outlook displays the custom action in the Action menu when an Inspector window is opened on the mail item. It also displays the custom action as a toolbar button. Figure 10.2. A custom action called "My custom action." Listing 10.9 shows a VSTO Outlook add-in that creates a custom action called My custom action. The CustomAction event is handled to set the subject when the custom action is invoked. Listing 10.9. A VSTO AddIn That Creates a Custom Action and Handles a Custom Action Event Public Class ThisApplication Private mailItem As Outlook.MailItem Private Sub ThisApplication_Startup(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Startup Dim ns As Outlook.NameSpace = Me.Session Dim inbox As Outlook.MAPIFolder = ns.GetDefaultFolder( _ Outlook.OlDefaultFolders.olFolderInbox) For Each o As Object In inbox.Items If TypeOf o Is Outlook.MailItem Then mailItem = o Else Exit For End If Next If mailItem Is Nothing Then MsgBox("Couldn't find a mail item.") Else MsgBox(String.Format( _ "Connected to the mail item {0}.", _ mailItem.Subject)) AddHandler mailItem.CustomAction, _ AddressOf MailItem_CustomAction Dim action As Outlook.Action = mailItem.Actions.Add() action.Name = "My custom action" action.ShowOn = Outlook.OlActionShowOn.olMenuAndToolbar action.ReplyStyle = _ Outlook.OlActionReplyStyle.olLinkOriginalItem End If End Sub Private Sub MailItem_CustomAction(ByVal action As Object, _ ByVal response As Object, ByRef cancel As Boolean) action = CType(action, Outlook.Action) Dim mailItem As Outlook.MailItem = CType(response, _ Outlook.MailItem) If action.Name = "My custom action" Then mailItem.Subject = "Created by my custom action" End If End Sub End Class | |