How to handle Outlook item’s Reply event: replying from a context-menu
This post is about how to intercept the user’s replying to a mail item via the context menu:
- For Outlook 2000 – 2002, there’s no need to handle the context-menu case
- For Outlook 2003, a solution is provided (a sample project is supplied)
- For Outlook 2007 – 2010, you use the ItemContextMenuDiaplay event (a sample project is supplied)
Let’s start.
In my previous posts, I explained how to connect to the Reply event of an Outlook.MailItem selected in the active explorer window or opened in the active inspector window. Let’s consider replying via the context menu.
First off, you can reply to one item only; that item is selected or right-clicked in an explorer window or is opened in an inspector window. You cannot reply to several items because the corresponding commands (including the one in the context menu) are disabled or hidden when several mail items are selected.
When you right-click an email in Outlook 2000 – 2002, the right-clicked item gets selected before the context menu is shown. This produces ExplorerSelectionChange and it means that in these Outlook versions you use Explorer.Activate and Explorer.SelectionChange events to get the selected item and connect to its events. This mechanism is described in this post.
In Outlook 2003, right-clicking an item doesn’t select it. This is the source of the problem: when in the Explorer window you select item #1, right-click item #2, then Explorer.Selection returns item #1. A solution is described below.
In Outlook 2007 and 2010, right-clicking an item doesn’t select it either. To get the right-clicked item(s), you use the ItemContextMenuDisplay event; it is available only in these Outlook versions. Note that in the object model of Outlook 2010, this event is marked as deprecated; still it works. The event occurs when you right-click an item(s) in the Outlook Explorer window before the corresponding context menu is shown.
The event signature specifies an Office.CommandBar object – you use it to customize the context menu to be displayed – and an Outlook.Selection object which you use to get the item(s) that were right-clicked.
C#:
private void adxOutlookEvents_ItemContextMenuDisplay(object sender, object commandBar, object target) { if (itemEvents.IsConnected) itemEvents.RemoveConnection(); Outlook.Selection selection = target as Outlook.Selection; ConnectToSelectedItem(selection); }
private void ConnectToSelectedItem(Outlook.Selection selection) { if (selection != null) { if (selection.Count == 1) { object item = selection.Item(1); if (item is Outlook.MailItem) { if (replyAllChecker.IsConnected) replyAllChecker.RemoveConnection(); replyAllChecker.ConnectTo(item, true); } else Marshal.ReleaseComObject(item); } } }
The variable replyAllChecker above represents an instance of the class that checks the number of recipients when the Reply event of the item occurs. It is taken from my previous posts, see here for instance.
And now about the Outlook 2003 case. The solution consists of three parts:
Handling the Click event. You intercept the Click event of a command bar button with ID = 354; this is the ID of the Reply command in the CommandBar UI. When the Click event occurs, the event handler is supplied with the CommandBarButton object that represents the button clicked. You use CommandBarButton.Parent to get the command bar on which the button is located. Then you make sure that the CommandBar object represents a context menu with the name “Context Menu”. Now you cancel the Click event (set the CancelDefault = true) and, still in the event handler of the Click event, you invoke CommandBarButton.Execute for the command bar button Open in the same context menu.
Handling opening the right-clicked item. Now, to handle the original item being opened, you connect to the NewInspector event. When it occurs, you get the inspector opening for that item and get the right-clicked item via Inspector.CurrentItem. This allows you to retrieve any required information from the source email. Then you connect to the events of the item and cancel the Open event of the item. As Ken Slovak pointed out here, you may need to close the inspector window, too (invoke Inspector.Close()).
Creating the response email. To create a reply, you retrieve the right-clicked item via NameSpace.GetItemFormId() and call MailItem.Reply(). In the supplied code, we connect to the item’s events before calling MailItem.Reply(). To initiate the creation of the reply, we use the SendMessage method and the OnSendMessage event of the add-in module; a timer will do, too.
Good luck!
Available downloads:
These sample COM Add-ins were developed using Add-in Express for Office and .net:
C# sample COM add-in (Outlook 2003)
VB.NET sample COM add-in (Outlook 2003)
C# sample COM add-in (Outlook 2007-2010)
VB.NET sample COM add-in (Outlook 2007-2010)