none
Writing new add-in RRS feed

  • Question

  • First off: Windows 7, Office 2010 32-Bit, Visual Studio 2010 Professional.

    Clearly I'm doing something wrong, or else not completing all the steps necessary.

    The add-in works, both in debug mode, and published. Only, the add-in doesn't seem to work until after I open a e-mail. The purpose behind the add-in is to provide a warning on 'Reply All'. Bear in mind there are a number of ways to execute a reply all: From the message itself, right-lick on the message from a mailbox view, or from the ribbon menu as applied to the selected message.

    But only after I first open the message does this work. Thereafter I can Reply All and get my warning message (either from clicking Reply All in the message or by any of the other two methods)

    Also. I published the code to a file location, and installed it. Not sure if my add-in is really complete as it references the VSTO file in Options/Advanced/Com Add-Ins. Screenshot provided. Note the 'Location', and also, the Load Behavior seems to conflict with the behavior I detailed above. Code follows. Any help/advice/suggestions would be greatly appreciated. Thanks.

     

    Public Class ThisAddIn
    
        Private WithEvents olkInspectors As Outlook.Inspectors
        Private WithEvents olkMessage As Outlook.MailItem
    
        Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
    
            Dim myOL As Outlook.Application
            myOL = Globals.ThisAddIn.Application
            olkInspectors = myOL.Inspectors()
            myOL = Nothing
    
        End Sub
    
        Private Sub ThisAddIn_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shutdown
    
            olkInspectors = Nothing
            olkMessage = Nothing
    
        End Sub
    
        Private Sub olkInspectors_NewInspector(ByVal Inspector As Microsoft.Office.Interop.Outlook.Inspector) Handles olkInspectors.NewInspector
    
            olkMessage = Nothing
            If Inspector.CurrentItem.Class = Outlook.OlObjectClass.olMail Then
                olkMessage = Inspector.CurrentItem
            End If
    
        End Sub
    
        Private Sub olkMessage_ReplyAll(ByVal Response As Object, ByRef Cancel As Boolean) Handles olkMessage.ReplyAll
    
            If MsgBox("Are you sure you want to Reply To All?", _
                      vbQuestion + vbYesNo, "Verify Reply to All (M&G)") = vbNo Then
                Cancel = True
            End If
    
        End Sub
    
    End Class
    


    Wednesday, January 25, 2012 3:15 PM

Answers

All replies

  • I don't understand - the only part of your code that is supposed to do anything IS firing: the ReplyAll event.  And that event is only hooked up when an e-mail window is opened, which is what you are supposed to do.  Unless you want ReplyAll to work when you reply to a message that is selected and not opened.  In that case you need to set olkMessage to the object returned in Explorer.Selection.
    Eric Legault
    MVP (Outlook)
    About me...
    Wednesday, January 25, 2012 4:06 PM
    Moderator
  • I don't understand - the only part of your code that is supposed to do anything IS firing: the ReplyAll event.  And that event is only hooked up when an e-mail window is opened, which is what you are supposed to do.  Unless you want ReplyAll to work when you reply to a message that is selected and not opened.  In that case you need to set olkMessage to the object returned in Explorer.Selection.
    Eric Legault
    MVP (Outlook)
    About me...

    Yes, as I suspected the code is incomplete. I imagine why it kind-of-sorta works after opening a message (but returning to the mailbox) and clicking Reply All from the ribbon, is that the olkMessage variable is set to the message still that I had opened.

    I don't want to muddy the waters anymore than that.

    So...Explorer.Selection. Okay. That'll cover both Right-Click/Reply All, as well as choosing Reply All from the ribbon? I am unfortunately not terribly familiar with the Outlook object library. Nevertheless I'm given the task of creating this Add-in.

    I'll fumble about in the Object Browser and documentation and see what I can do. Thanks. 


    • Edited by ITMn0403 Wednesday, January 25, 2012 4:22 PM
    Wednesday, January 25, 2012 4:18 PM
  • The error handler you're adding is being added only when NewInspector() fires and you instantiate the olkMessage item. Then the ReplyAll() event will fire on that item when the Reply All  ribbon button is clicked on the open item.

    To handle the other ways a ReplyAll can occur you have to handle each case separately. For example, a user might click Reply All on a selected item in a folder view. In that case you'd need to handle a click event for that ribbon button, as well as handling ReplyAll from a right-click context menu, and so on.

    This article may help with that: http://msdn.microsoft.com/en-us/library/ee692172.aspx

     


    Ken Slovak MVP - Outlook
    Wednesday, January 25, 2012 4:24 PM
    Moderator
  • The error handler you're adding is being added only when NewInspector() fires and you instantiate the olkMessage item. Then the ReplyAll() event will fire on that item when the Reply All  ribbon button is clicked on the open item.

    To handle the other ways a ReplyAll can occur you have to handle each case separately. For example, a user might click Reply All on a selected item in a folder view. In that case you'd need to handle a click event for that ribbon button, as well as handling ReplyAll from a right-click context menu, and so on.

    This article may help with that: http://msdn.microsoft.com/en-us/library/ee692172.aspx

     


    Ken Slovak MVP - Outlook
    Ken: I appreciate your help (I do!). Only I'm trying to figure out how XML Markup examples are relevant to me need to create an event handler to 'handle' these other instances where a user can execute Reply All
    Wednesday, January 25, 2012 4:32 PM
  • You need the article Ken is referring to in order to understand how to trap right-click context menus.  If you've designed your ribbon controls with VSTO's Ribbon Designer, you can easily trap control click events through the code it creates for you (without requiring hand-writing the xml).

    Also keep in mind that there may be no way to trap a user right-clicking a message that's NOT selected and selecting Reply/ReplyAll.  Try it and you'll see - the selection doesn't change, hence no way to get the message from the Explorer.Selection object.  It's an edge case, but be wary of this hole.


    Eric Legault
    MVP (Outlook)
    About me...
    Wednesday, January 25, 2012 4:39 PM
    Moderator
  • You could handle the click events for the ReplyAll buttons and context menus by adding onAction callbacks for those button clicks. In that case you'd get notified for any possible ReplyAll.
     
    Just handling NewInspector() will tell you when every new item is opened, by ReplyAll or by Reply or a new item or whatever. From there finding out if the item was a reply all is a chore. You'd have to find the original item by finding an item with the same ConversationTopic and a ConversationIndex value that matches the one in the new item except for being 1 time/date stamp shorter.
     
    Then you'd need to get the PR_LAST_VERB_EXECUTED property using PropertyAccessor on that original item with a DASL property tag of "http://schemas.microsoft.com/mapi/proptag/0x10810003", looking for a value of 103 (EXCHIVERB_REPLYTOALL).

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "ITMn0403" <=?utf-8?B?SVRNbjA0MDM=?=> wrote in message news:3673bb2f-fc98-41e4-8d31-ca347ee043e5...
     
    Ken: I appreciate your help (I do!). Only I'm trying to figure out how XML Markup examples are relevant to me need to create an event handler to 'handle' these other instances where a user can execute Reply All

    Ken Slovak MVP - Outlook
    Wednesday, January 25, 2012 4:39 PM
    Moderator
  • That edge case is covered by handling the context menu click for reply all, of course.

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Eric Legault [Outlook MVP]" <=?utf-8?B?RXJpYyBMZWdhdWx0IFtPdXRsb29rIE1WUF0=?=> wrote in message news:32175d4e-8a32-4bed-a7eb-ea6e7fcfcc1a...

    You need the article Ken is referring to in order to understand how to trap right-click context menus.  If you've designed your ribbon controls with VSTO's Ribbon Designer, you can easily trap control click events through the code it creates for you (without requiring hand-writing the xml).

    Also keep in mind that there may be no way to trap a user right-clicking a message that's NOT selected and selecting Reply/ReplyAll.  Try it and you'll see - the selection doesn't change, hence no way to get the message from the Explorer.Selection object.  It's an edge case, but be wary of this hole.


    Eric Legault
    MVP (Outlook)
    About me...

    Ken Slovak MVP - Outlook
    Wednesday, January 25, 2012 4:41 PM
    Moderator
  • Does the click event handler for that then provide the "ghost selected" object in a parameter??
    Eric Legault
    MVP (Outlook)
    About me...
    Wednesday, January 25, 2012 4:43 PM
    Moderator
  • You need the article Ken is referring to in order to understand how to trap right-click context menus.  If you've designed your ribbon controls with VSTO's Ribbon Designer, you can easily trap control click events through the code it creates for you (without requiring hand-writing the xml).

    Also keep in mind that there may be no way to trap a user right-clicking a message that's NOT selected and selecting Reply/ReplyAll.  Try it and you'll see - the selection doesn't change, hence no way to get the message from the Explorer.Selection object.  It's an edge case, but be wary of this hole.


    Eric Legault
    MVP (Outlook)
    About me...
    I'm niether designing nor modifying the ribbon in any way. The only reason I mentioned the ribbon is because there resides one way to Reply All to a selected message.
    Wednesday, January 25, 2012 4:44 PM
  • You could handle the click events for the ReplyAll buttons and context menus by adding onAction callbacks for those button clicks. In that case you'd get notified for any possible ReplyAll.
     
    Just handling NewInspector() will tell you when every new item is opened, by ReplyAll or by Reply or a new item or whatever. From there finding out if the item was a reply all is a chore. You'd have to find the original item by finding an item with the same ConversationTopic and a ConversationIndex value that matches the one in the new item except for being 1 time/date stamp shorter.
     
    Then you'd need to get the PR_LAST_VERB_EXECUTED property using PropertyAccessor on that original item with a DASL property tag of "http://schemas.microsoft.com/mapi/proptag/0x10810003", looking for a value of 103 (EXCHIVERB_REPLYTOALL).

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "ITMn0403" <=?utf-8?B?SVRNbjA0MDM=?=> wrote in message news:3673bb2f-fc98-41e4-8d31-ca347ee043e5...
     
    Ken: I appreciate your help (I do!). Only I'm trying to figure out how XML Markup examples are relevant to me need to create an event handler to 'handle' these other instances where a user can execute Reply All

    Ken Slovak MVP - Outlook
    Ah! Sweet Jesus.
    Wednesday, January 25, 2012 4:44 PM
  • In that case the IRibbonControl.Context that's passed to your handler is a Selection collection that you'd iterate to get the items that are members of the selection.

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Eric Legault [Outlook MVP]" <=?utf-8?B?RXJpYyBMZWdhdWx0IFtPdXRsb29rIE1WUF0=?=> wrote in message news:931ef90f-ee48-4455-8e58-d51a751edb34...
    Does the click event handler for that then provide the "ghost selected" object in a parameter??
    Eric Legault
    MVP (Outlook)
    About me...

    Ken Slovak MVP - Outlook
    Wednesday, January 25, 2012 6:17 PM
    Moderator
  • And you're certain that it returns the item that's right-clicked and NOT actually selected/current?  Sorry, just want to be clear.  Because in that weird situation it would only be one item, as you can't NOT select multiple items that's not selected and right-click them.
    Eric Legault
    MVP (Outlook)
    About me...
    Wednesday, January 25, 2012 7:05 PM
    Moderator
  • What's the old expression, that's left as an exercise for the student? Try it and see <g>

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Eric Legault [Outlook MVP]" <=?utf-8?B?RXJpYyBMZWdhdWx0IFtPdXRsb29rIE1WUF0=?=> wrote in message news:a62a100a-dda2-450f-9eff-316a508ba744...
    And you're certain that it returns the item that's right-clicked and NOT actually selected/current?  Sorry, just want to be clear.  Because in that weird situation it would only be one item, as you can't NOT select multiple items that's not selected and right-click them.
    Eric Legault
    MVP (Outlook)
    About me...

    Ken Slovak MVP - Outlook
    Wednesday, January 25, 2012 7:17 PM
    Moderator
  • I decided to test this and it does work correctly. Using this Explorer ribbon XML:
     

    <?xml version="1.0" encoding="utf-8"?>

    <customUI onLoad="Ribbon_OnLoad" xmlns="http://schemas.microsoft.com/office/2009/07/customui">

        <contextMenus>

            <contextMenu idMso="ContextMenuMailItem">

                <button id="MyContextMenuMailItem"

                    label="ContextMenuMailItem"

                    onAction="OnMyButtonClick"/>

            </contextMenu>

        </contextMenus>

    </customUI>

    from an article Randy wrote, I added this handler to my Outlook 2010 test-bed addin, whic worked perfectly. If I r-clicked on the selected item in the Explorer I got that subject, if I r-clicked on something else I got that item's subject:
     

    public void OnMyButtonClick(Ribbon.IRibbonControl control)

    {

        try

        {

            Debug.WriteLine(control.Id.ToString());

            if (control.Context is Outlook.Selection)

            {

                Outlook.Selection sel = control.Context as Outlook.Selection;

                Debug.WriteLine(sel.Count.ToString());

                if (sel[1] is Outlook.MailItem)

                {

                    Outlook.MailItem m = sel[1] as Outlook.MailItem;

                    Debug.WriteLine(m.Subject);

                }

            }

        }

        catch (Exception ex)

        {

            Debug.WriteLine(ex.Message);

        }

    }


    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     

    Ken Slovak MVP - Outlook
    Wednesday, January 25, 2012 9:25 PM
    Moderator
  • http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_event.replyall.aspx

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_10_event.replyall.aspx

     

    Would it be plausible to use either one of the above event handlers to catch the ReplyAll event and give a warning (and the ability to cancel)?

    Thanks 

    Thursday, January 26, 2012 9:57 PM
  • Both of those require an instantiated item (MailItem, AppointmentItem, etc.) which is declared WithEvents or to which you add that error handler. That's fine with an Inspector, where you have an open item. It also works with a selected item where you handle Explorer.SelectionChange() and instanatate an item of the correct type and set the event handler.
     
    For more than 1 open Inspector or selected item I'd use a wrapper class that has the event handler and any other handlers and code and add an instance of the class to a collection/list/dictionary/whatever to keep it alive.
     
    That would not handle the case of a non-selected item being right-clicked and bringing up a context menu.
     

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "ITMn0403" <=?utf-8?B?SVRNbjA0MDM=?=> wrote in message news:7aa42bea-5763-4e53-a4ee-8c479885286b...

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_event.replyall.aspx

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_10_event.replyall.aspx

     

    Would it be plausible to use either one of the above event handlers to catch the ReplyAll event and give a warning (and the ability to cancel)?

    Thanks 


    Ken Slovak MVP - Outlook
    Thursday, January 26, 2012 10:32 PM
    Moderator
  • Both of those require an instantiated item (MailItem, AppointmentItem, etc.) which is declared WithEvents or to which you add that error handler. That's fine with an Inspector, where you have an open item. It also works with a selected item where you handle Explorer.SelectionChange() and instanatate an item of the correct type and set the event handler.
     
    For more than 1 open Inspector or selected item I'd use a wrapper class that has the event handler and any other handlers and code and add an instance of the class to a collection/list/dictionary/whatever to keep it alive.
     
    That would not handle the case of a non-selected item being right-clicked and bringing up a context menu.
     

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "ITMn0403" <=?utf-8?B?SVRNbjA0MDM=?=> wrote in message news:7aa42bea-5763-4e53-a4ee-8c479885286b...

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_event.replyall.aspx

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_10_event.replyall.aspx

     

    Would it be plausible to use either one of the above event handlers to catch the ReplyAll event and give a warning (and the ability to cancel)?

    Thanks 


    Ken Slovak MVP - Outlook

    So I've managed to handle two of the three events: Explorer.SelectionChange, and Explorer.Activate.

    As I've found through testing in a real-to-life scenario, people may have several e-mails open, switch back to the Outlook application, and back to the already opened e-mail. As you suggest and as I've found capturing the Reply All event will require more coding.

    I don't honestly know what a 'wrapper class' is. Yeah, I'm going to Google it, look into it...but how I'll implement it in my case I would really have no clue.

    So as to your answer being the answer I thank you. My answer however is yet unaswered.

     
    • Edited by ITMn0403 Thursday, February 9, 2012 5:54 PM
    Thursday, February 9, 2012 5:52 PM
  • Here is the current code for my add-in. It is incomplete, and perhaps even incorrectly implemented. It does however work in some cases. Were you to launch Outlook and first either click Reply All from the ribbon, from the right-click context menu or directly from the message itself, it does work. But as I've attempted to explain, you begin using Outlook in a real-to-life fashion, i.e. opening multiple e-mails, switching back to the Outlook application window, etc. then I run into problems.

    I suspect it is because my MailItem (olkMailItem) object is getting reset/unset by actions precipitated by the user (hence event-driven programming)

    Code follows.

    Imports Microsoft.Office.Interop.Outlook
    
    Public Class ThisAddIn
    
        Public WithEvents olkEx As Outlook.Explorer
    
        Public WithEvents olkMailItem As Outlook.MailItem
    
        Private Sub ThisAddIn_Startup() Handles Me.Startup
    
            Dim myOL As Outlook.Application
            myOL = Globals.ThisAddIn.Application
            olkEx = myOL.ActiveExplorer
    
        End Sub
    
        Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
    
        End Sub
    
        Private Sub olkEx_Activate() Handles olkEx.Activate
    
            If olkEx.Selection.Count > 0 Then
                olkMailItem = olkEx.Selection.Item(1)
            Else
                olkMailItem = olkEx.Application.ActiveInspector.CurrentItem
            End If
    
        End Sub
    
    
        Private Sub olkMailItem_ReplyAll(ByVal Response As Object, ByRef Cancel As Boolean) Handles olkMailItem.ReplyAll
    
            If olkMailItem.Class = Outlook.OlObjectClass.olMail Then
    
                If MsgBox("Are you sure you want to Reply To All?", _
                vbQuestion + vbYesNo, "Verify Reply to All (M&G)") = vbNo Then
                    Cancel = True
                End If
            End If
    
        End Sub
    
        Private Sub olkEx_SelectionChange() Handles olkEx.SelectionChange
            If olkEx.Selection.Count > 0 Then
                olkMailItem = olkEx.Selection.Item(1)
            End If
    
        End Sub
    
    End Class


    Thursday, February 9, 2012 6:03 PM
  • You can look at the download samples I have for VSTO and shared addins for Outlook 2007 (they're in VS2005) on my Web site. They all show examples of wrapper classes for Inspectors and Explorers: http://www.slovaktech.com/outlook_2007_templates.htm
     
    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "ITMn0403" <=?utf-8?B?SVRNbjA0MDM=?=> wrote in message news:7aa42bea-5763-4e53-a4ee-8c479885286b...

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_event.replyall.aspx

    http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.itemevents_10_event.replyall.aspx

     

    Would it be plausible to use either one of the above event handlers to catch the ReplyAll event and give a warning (and the ability to cancel)?

    Thanks 


    Ken Slovak MVP - Outlook

    So I've managed to handle two of the three events: Explorer.SelectionChange, and Explorer.Activate.

    As I've found through testing in a real-to-life scenario, people may have several e-mails open, switch back to the Outlook application, and back to the already opened e-mail. As you suggest and as I've found capturing the Reply All event will require more coding.

    I don't honestly know what a 'wrapper class' is. Yeah, I'm going to Google it, look into it...but how I'll implement it in my case I would really have no clue.

    So as to your answer being the answer I thank you. My answer however is yet unaswered.

     

    Ken Slovak MVP - Outlook
    Thursday, February 9, 2012 6:05 PM
    Moderator