none
Outlook 2010 and Using Windows Forms RRS feed

  • Question

  • When launching a Windows form in Outlook 2010 in a custom add-in, while the form is open, it does not allow you to do anything else in Outlook until you close out the Windows form.

    So if I have the Windows form open, I can minimize the form but I can not browse around my Outlook client to look at calendar entries or look at mail items until I close out the Windows form.

    Is there a way to launch the Windows form that will allow me to work the Outlook client without having to close out of the Windows form?

    Here is the code that I am currently using to launch the Windows form from within a button on a custom Outlook Ribbon:

    newAR dlgW = new newAR();
                dlgW.ShowDialog();

    We are using:

    Visual Studio 2010

    C#

    Outlook 2010 32 bit

    Thursday, January 9, 2014 1:51 PM

Answers

All replies

  • ShowDialog() opens a window modally. No code can run in your addin after that call until the dialog is closed, if the code is running on the main thread. Note that Outlook object model code must run on the main thread.

    The user interface however shouldn't be hung in that case unless you're running Outlook code in the user form or you made the form TopMost.


    Ken Slovak MVP - Outlook

    Thursday, January 9, 2014 2:57 PM
  • Hello niyack,

    > Is there a way to launch the Windows form that will allow me to work the Outlook client without having to close out of the Windows form?

    Yes, you need to use the Show method instead of the ShowDialog one as Ken already suggested. But you need to choose the method which accepts an instance of the IWin32Window interface. This way you can specify the parent window for your form and keep the form always on top of your parent form (not be hidden by the main window).

    First of all, you need to define a class which implements IWin32Window interface:

    public class WindowImplementation : System.Windows.Forms.IWin32Window
    {
        private IntPtr _hwnd;
    
        public WindowImplementation(IntPtr handle)
        {
            _hwnd = handle;
        }
    
        public IntPtr Handle
        {
            get 
            {
                return _hwnd; 
            }
        }
    }

    Then you need to find a handle of the parent Outlook window. For example, you can use the FindWindow function. Or just find Outlook in the list of running procesess and use the MainWindowHandle of the System.Diagnostics.Process class. Just pass the window handle to the ctor of the WindowInplementation class and call the Show method passing the just created object as an argument.

    Finally, you can read more about this in the Creating a IWin32Window from a Win32 Handle article.


    Thursday, January 9, 2014 3:27 PM
  • If Outlook 2007 or later is used it's easy to get the window handle, which can be passed to the IWin32Window class implementation. If Outlook 2003 or earlier is used then you have to use FindWindow() and so on.

    The Outlook 2007 or later window (ActiveExplorer or ActiveInspector or ActiveWindow) can be gotten and cast as an IOleWindow, which can be defined with the following COM Import:

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("00000114-0000-0000-C000-000000000046")]
    iternal interface IOleWindow { void GetWindow(out System.IntPtr phwnd); void ContextSensitiveHelp([In] bool fEnterMode);}

    You can then use code like this, where "win" is the window from Outlook:

    win = this._insp as Win32UI.IOleWindow;  // in this case the window is ActiveInspector
    IntPtr ptr = IntPtr.Zero;
    win.GetWindow(out ptr);

    The pointer can then be passed to the IWin32Window class implementation.


    Ken Slovak MVP - Outlook

    Thursday, January 9, 2014 4:05 PM
  • This worked perfectly thanks!!!!
    • Marked as answer by niyack Thursday, January 9, 2014 4:43 PM
    Thursday, January 9, 2014 4:43 PM