none
How to find the correct Outlook Explorer RRS feed

  • Question

  • Hello

    I've created a Outlook VSTO add-in that shows a Custom Task Pane in the Outlook Explorer and a Custom Task Pane in the Outlook Inspector window.

    I've created a wrapper class for the Explorer to handle the Close event, a wrapper class for the Inspector to also handle the Close event and a CustomTaskPane wrapper to handle the VisibleChanged event. The wrappers are stored in List objects in the ThisAddIn.

    It all works fine for the Inspector windows, but the Explorer windows are a nightmare as the Explorer window HashCode changes.

    For example

    If you attach a method to handle the Application.Explorers.NewExplorer event when the addin starts up to wrap the Explorer and handle the Close event, and add a custom ribbon button. When the ribbon button is clicked you call the GetExplorer method on the current MAPIFolder. This causes a new Explorer window to be created and raises the NewExplorer raise.

    So I would expect the Explorer object passed into the NewExplorer event to have the same HashCode value as the Explorer returned by the MAPIFolder.GetExplorer method. They do not.

    Because they have different values I can't workout which CustomTaskPanes exist in Explorer when the Close event is raised. So I can't tidy up properly and exceptions occur further down stream when it tries to access an Explorer that's been closed.

    The Inspector windows work fine and keep the same HashCode, so I can workout the CustomTaskPanes that belong to the Inspector window and tidy up properly.

    Has anyone had the same problem, and if so how did you resolve it?

    Or is there a better/another way to find the correct Explorer object other than using the Equals method?

    Many thanks


    • Edited by M_Collard Thursday, February 7, 2013 4:23 PM Expanded the final question
    Thursday, February 7, 2013 4:10 PM

Answers

  • That's what I'm finding that different COM objects are returned for the same Explorer window. D'oh.

    So I've had an idea. Instead of putting all the tidy up code in the ExplorerWrapper.Close event handler (where it tries to find all the CustomTaskPaneWrappers linked to the closing Explorer and remove them from the _customTaskPaneWrappers list), I handle the Explorer.Close event in the CustomTaskPane wrapper so it can raise an event (WindowClose) to indicate the linked Window is closing. Then in the ThisAddIn class I handle the CustomTaskPaneWrapper.WindowClose event and remove the passed CustomTaskPaneWrapper object from the _customTaskPaneWrappers list.

    Not quite how I wanted to do it, but seems to do the trick.

    Thanks for your help Dmitry.

    • Marked as answer by M_Collard Friday, February 8, 2013 1:00 PM
    Friday, February 8, 2013 8:59 AM

All replies

  • What hash code exactly do you mean?

    Why do you call MAPIFolder.GetExplorer? Why not set Application.ActiveExplorer.CurrentFolder property?


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

    Thursday, February 7, 2013 4:34 PM
  • Hi Dmitry

    When the Explorer.Close event is raised my ExplorerWrapper raises it's own Close event which is handled in the ThisAddIn object. In the ExplorerWrapper_Close handler method it loops round the _customTaskPaneWrappers list to find all the CustomTaskPanes that exist in the closing Explorer so it can tidy properly.

    The problem is it doesn't find the custom task panes in the Explorer when it uses the Equals method

    e.g.

    CustomTaskPane.Window.Equals(closingExplorer)

    Looking at it more closely I noticed that the GetHashCode method returned different values which lead me to believe they are different Explorer objects pointing to the same Explorer.

    P.S.

    I was using the GetExplorer method to open a new Explorer window to raise the Explorers.NewExplorer event as an example.

    Thursday, February 7, 2013 5:12 PM
  • Different COM objects can refer to the same UI object. You can retrieve the Explorer's HWND using IOleWindow (I have never trried that in .Net) and compare the HWNDs, but that still sounds like a hack.

    Why not store a pointer to your task pane in your Explorer wrapper? This way you will never have to search for anything.


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


    Thursday, February 7, 2013 5:22 PM
  • That's what I'm finding that different COM objects are returned for the same Explorer window. D'oh.

    So I've had an idea. Instead of putting all the tidy up code in the ExplorerWrapper.Close event handler (where it tries to find all the CustomTaskPaneWrappers linked to the closing Explorer and remove them from the _customTaskPaneWrappers list), I handle the Explorer.Close event in the CustomTaskPane wrapper so it can raise an event (WindowClose) to indicate the linked Window is closing. Then in the ThisAddIn class I handle the CustomTaskPaneWrapper.WindowClose event and remove the passed CustomTaskPaneWrapper object from the _customTaskPaneWrappers list.

    Not quite how I wanted to do it, but seems to do the trick.

    Thanks for your help Dmitry.

    • Marked as answer by M_Collard Friday, February 8, 2013 1:00 PM
    Friday, February 8, 2013 8:59 AM
  • What I usually do in such circumstances is to keep a list of keys for a wrapper collection in the Explorer or Inspector wrapper class. That makes it easy to know which items are related to which windows.

    --
    Ken Slovak
    [MVP-Outlook]
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
    "M_Collard" <=?utf-8?B?TV9Db2xsYXJk?=> wrote in message news:5afab1cd-0698-4379-b7cb-e4fda43bbe1c...

    That's what I'm finding that different COM objects are returned for the same Explorer window. D'oh.

    So I've had an idea. Instead of putting all the tidy up code in the ExplorerWrapper.Close event handler (where it tries to find all the CustomTaskPaneWrappers linked to the closing Explorer and remove them from the _customTaskPaneWrappers list), I handle the Explorer.Close event in the CustomTaskPane wrapper so it can raise an event (WindowClose) to indicate the linked Window is closing. Then in the ThisAddIn class I handle the CustomTaskPaneWrapper.WindowClose event and remove the passed CustomTaskPaneWrapper object from the _customTaskPaneWrappers list.

    Not quite how I wanted to do it, but seems to do the trick.

    Thanks for your help Dmitry.


    Ken Slovak MVP - Outlook
    Friday, February 8, 2013 6:53 PM