none
Outlook 365 - ActiveInspector() returns the incorrect object RRS feed

  • Question

  • Hello,

    With Outlook 365, it's observed that when multiple windows are open, ActiveInspector() returns the incorrect inspector object. This works well with Outlook 2010 and Outlook 2016.

    Below is the sample block (ribbon menu callback IsVisible) where this can be reproduce and it has an alternate approach as well which I have mentioned with next block. 

     public bool IsVisible(object control)
            {
    var inspector = Globals.ThisAddIn.Application.ActiveInspector();
                if (inspector != null && inspector.CurrentItem != null)
                {
                    Outlook.AppointmentItem apt = inspector.CurrentItem as Outlook.AppointmentItem;
                    if (apt != null) MessageBox.Show("Appointment item");
                    Outlook.MailItem mail = inspector.CurrentItem as Outlook.MailItem;
                    if (mail != null) MessageBox.Show("Mail item");
                }
                return true;
            }

    Alternate approach using control.context

     public bool IsVisible(object control)
            {
                Outlook.Inspector inspector = null;
                if (control is Microsoft.Office.Core.IRibbonControl)
                {
                    Microsoft.Office.Core.IRibbonControl ribbonControl = control as Microsoft.Office.Core.IRibbonControl;
                    if (ribbonControl.Context is Outlook.Inspector)
                    {
                        inspector = ribbonControl.Context as Outlook.Inspector;
                    }
                }
                if (inspector != null && inspector.CurrentItem != null)
                {
                    Outlook.AppointmentItem apt = inspector.CurrentItem as Outlook.AppointmentItem;
                    if (apt != null) MessageBox.Show("Appointment item");
                    Outlook.MailItem mail = inspector.CurrentItem as Outlook.MailItem;
                    if (mail != null) MessageBox.Show("Mail item");
                }
                return true;
            }

    My question is alternate approach will work for this callback scenario but what about if we have used ActiveInspector() method at places where there is no ribbon control object. ActiveInspector() method is globally available method which can give you active inspector object and that can be used to for various scenarios and not limited to call backs. 

    Is this something this issue is limited to callbacks and at other places it works? Is there any Microsoft documentation about this known issue and workaround for it ? And is there any plan to fix this issue for any next version of O365 ? 


    Thanks,


    • Edited by ManojPatel Monday, February 10, 2020 5:00 PM
    Monday, February 10, 2020 5:00 PM

All replies

  • For the control and ribbon callbacks, you should never use ActiveInspector. Your second approach is correct - always us IRibbonControl.Context and cast it to an Inspector or Explorer object as appropriate.

    What is you other scenario where you are forced to use ActiveInspector? Keep in mind that Outlook might have a different idea what an active inspector is. E.g. when inspector is just being displayed (e.g. in the Inspectors.NewInspector event) and it is not yet visible, ActiveInspector will not return that inspector.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, February 10, 2020 5:13 PM
  • Thanks for your response. 

    As ActiveInspector() used to work with other versions of outlook there can be different use of it. Below are 2 scenarios but I think this can be used at multiple places based on need.

    1. 

    While opening  received email if you attach event "WordApp.WindowSelectionChange" and open multiple emails, this event gets trigger multiple times for all the opened windows even though you did selection change for specific email. Ideally that event should get trigger for specific active email window but that's not a case.

    For such case ActiveInspector() will give us active email where operation has been done to perform logic.

     2. 

    Attach "AppointmentItem.Write" event from "Explorer.SelectionChange" event. This is required for any inline operations to particular meeting within calendar folder. 
    Now, on the "AppointmentItem.Write" event to identify for which AppointmentItem event got triggered ActiveInspector() method helps. 



    ManojPatel

    Monday, February 10, 2020 5:29 PM
  • 1. Can you work with the Selection object passed as the argument? From there, you can get to Selection.Document, and that document is the one returned by Inspector.WordEditor

    2. But why do you need an inspector if you are working with the AppointmentItem.Write event? If you are tracking multiple items, you can create a wrapper class that takes an AppointmentItem object as a parameter and hooks the AppointmentItem.Write event to its method. When the event fires, the method of the wrapper class has access to the wrapper class's property that holds a pointer to that particular AppointmentItem object.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Monday, February 10, 2020 5:51 PM
  • Thank you. Below i have added my comments. 

    1. Can you work with the Selection object passed as the argument? From there, you can get to Selection.Document, and that document is the one returned by Inspector.WordEditor

    --> yes  but for all the events we get Selection object (different values) so we can't execute functional logic for all the opened emails. Only option I got was to identify Active window and perform logic. 

    2. But why do you need an inspector if you are working with the AppointmentItem.Write event? If you are tracking multiple items, you can create a wrapper class that takes an AppointmentItem object as a parameter and hooks the AppointmentItem.Write event to its method. When the event fires, the method of the wrapper class has access to the wrapper class's property that holds a pointer to that particular AppointmentItem object.

    --> this may work.

    Here question is with plugins developed with outlook 2010 and 2016 there can be many these kind of places where ActiveInspector() have been used (as it used to work) and suddenly with Outlook 365 client it is required to change everything.

    Do you have any idea whether ActiveInspector() method issue is limited to ribbon callbacks and at other places it can work ? Or it's like we cannot use that ever with Outlook 365 ? Any proper documentation would really help to decide migration changes and efforts.

    Thanks for your help on this. 


    ManojPatel

    Tuesday, February 11, 2020 9:51 AM
  • With #1 "WordApp.WindowSelectionChange" event, if I use ActiveInspector() method then it gives correct result. Any idea why it only gives wrong result inside ribbon call backs ? 

    If that's an expected behavior then may be i can use the "ribbonControl.Context as Outlook.Inspector;" inside ribbon call backs and at other places i can keep using ActiveInspector() method?



    ManojPatel

    Wednesday, February 12, 2020 3:56 PM
  • Ribbon callback can fire for an inspector that is not yet visible/active, hence ActiveInspector can return a different Inspector object.

    More than that, ribbon callback can fire for multiple inspectors, both active and inactive. You must always use the RibbonControl.Context for the ribbon callbacks.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Wednesday, February 12, 2020 4:10 PM
  • The first point make sense that ribbon callback can fire for an inspector that is not yet visible and hence ActiveInspector can return different Inspector object but that started happening from O365 somehow.

    Can we say that inside ribbon call back it must not be use but at any other places that can be used without any issues ?

    It would be really good if some documentation available from Microsoft on this to avoid any confusion.

    Thanks for your help on this. 


    ManojPatel

    Wednesday, February 12, 2020 6:59 PM
  • For #1, it's always been like that - when a ribbon is being refreshed, the callbacks will fire for all inspectors, both active and inactive.

    And for #2, I still don't think you need ActiveInspector, certainly not for the Write event handler.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Wednesday, February 12, 2020 7:39 PM
  • #1 - yes call backs gets fired for all inspectors, both active and inactive but ActiveInspector() gives correct result. I just compared it with Outlook 2010, 2016 and O365 only issue is with O365. Tried with very basic vsto plugin. This has been confirmed with other plugins as well and result is same.

    #2 - may not need for Write event handler but for event like this WordApp.WindowSelectionChange definitely needed.

    And if ActiveInspector() doesn't mean to return correct active inspector object then why that method is there ? there could be some places it may not work but should not be everywhere.


    ManojPatel

    Thursday, February 13, 2020 10:58 AM
  • 1. It is a really moot point - if you can get Inspector from RibbonControl.Context , there is no point using ActiveInspector.

    2. Not really - create a wrapper that holds Inspector and Document objects as properties, create WindowSelectionChange event handler as a method on that wrapper object, then when the event fires, you have access to the Inspector object.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, February 13, 2020 3:08 PM
  • #2 - Yes, using wrapper we would have access to the Inspector object however, here problem is WindowSelectionChange event gets fire multiple times. So that if you have 2 email windows open 2 times that event will get fire for both the inspectors and we want to perform logic only for the active inspector where from where selection change happened. 

    Logic is compare the Inspector object we hold with ActiveInspector() to confirm particular event happened is for active inspector window or now. 

    Hope it's bit clear now.

    Thank you. 


    ManojPatel

    Wednesday, February 19, 2020 12:18 PM