locked
Get Windows Handle of Outlook? RRS feed

  • Question

  • Is there a way I can get the handle of Outlook? I've been told to use Application.Hwnd but it doesn't seem to work.
    Saturday, September 12, 2009 5:53 AM

Answers

  • Hi Omnicorder,

    see this:

    ///<summary>
    /// This class retrieves the IWin32Window from the current active Outlook window.
    /// This could be used to set the parent for Windows Forms and MessageBoxes.
    ///</summary>
    ///<example>
    /// OutlookWin32Window parentWindow = new OutlookWin32Window (ThisAddIn.OutlookApplication.ActiveWindow ());   
    /// MessageBox.Show (parentWindow, "This MessageBox doesn't go behind Outlook !!!", "Attention !", MessageBoxButtons.Ok , MessageBoxIcon.Question );
    ///</example>
    internal class OutlookWin32Window : IWin32Window {
     
        ///<summary>
        /// The <b>FindWindow</b> method finds a window by it's classname and caption.
        ///</summary>
        ///<param name="lpClassName">The classname of the window (use Spy++)</param>
        ///<param name="lpWindowName">The Caption of the window.</param>
        ///<returns>Returns a valid window handle or 0.</returns>
        [DllImport("user32")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
     
        #region IWin32Window Members
     
        ///<summary>
        /// This holds the window handle for the found Window.
        ///</summary>
        IntPtr _windowHandle = IntPtr.Zero;
     
        ///<summary>
        /// The <b>Handle</b> of the Outlook WindowObject.
        ///</summary>
        public IntPtr Handle {
            get { return _windowHandle; }
        }
     
        #endregion
     
        ///<summary>
        /// The <b>OutlookWin32Window</b> class could be used to get the parent IWin32Window for Windows.Forms and MessageBoxes.
        ///</summary>
        ///<param name="windowObject">The current WindowObject.</param>
        public OutlookWin32Window(object windowObject) {
            string caption = windowObject.GetType().InvokeMember("Caption", System.Reflection.BindingFlags.GetProperty, null, windowObject, null).ToString();
     
            // try to get the HWND ptr from the windowObject / could be an Inspector window or an explorer window
            _windowHandle = FindWindow("rctrl_renwnd32\0", caption);
        }
    }



    If you want to get the main HWnd of the Outlook process,
    get the Process of Outlook and use Process.Handle.


    Hope this helps,
    greets - Helmut

    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    • Marked as answer by Bessie Zhao Friday, September 18, 2009 10:37 AM
    Saturday, September 12, 2009 6:12 AM
    Answerer
  • Hi,

    While that will work, at best it is an incomplete approach because if there are multiple instances of Outlook running, there is no guarantee as to which instance will occupy the first element of the Process array.  Nor is there any simple way to disambiguate between the running instances.

    If this is a VSTO customization, you will want to use Process.GetCurrentProcess().  This will return the Process wrapper for the instance of Outlook that your code is running in.

    Sincerely,

    Geoff Darst
    Microsoft VSTO Team
    • Marked as answer by Bessie Zhao Friday, September 18, 2009 10:37 AM
    Wednesday, September 16, 2009 3:56 PM
    Answerer

All replies

  • Hi Omnicorder,

    see this:

    ///<summary>
    /// This class retrieves the IWin32Window from the current active Outlook window.
    /// This could be used to set the parent for Windows Forms and MessageBoxes.
    ///</summary>
    ///<example>
    /// OutlookWin32Window parentWindow = new OutlookWin32Window (ThisAddIn.OutlookApplication.ActiveWindow ());   
    /// MessageBox.Show (parentWindow, "This MessageBox doesn't go behind Outlook !!!", "Attention !", MessageBoxButtons.Ok , MessageBoxIcon.Question );
    ///</example>
    internal class OutlookWin32Window : IWin32Window {
     
        ///<summary>
        /// The <b>FindWindow</b> method finds a window by it's classname and caption.
        ///</summary>
        ///<param name="lpClassName">The classname of the window (use Spy++)</param>
        ///<param name="lpWindowName">The Caption of the window.</param>
        ///<returns>Returns a valid window handle or 0.</returns>
        [DllImport("user32")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
     
        #region IWin32Window Members
     
        ///<summary>
        /// This holds the window handle for the found Window.
        ///</summary>
        IntPtr _windowHandle = IntPtr.Zero;
     
        ///<summary>
        /// The <b>Handle</b> of the Outlook WindowObject.
        ///</summary>
        public IntPtr Handle {
            get { return _windowHandle; }
        }
     
        #endregion
     
        ///<summary>
        /// The <b>OutlookWin32Window</b> class could be used to get the parent IWin32Window for Windows.Forms and MessageBoxes.
        ///</summary>
        ///<param name="windowObject">The current WindowObject.</param>
        public OutlookWin32Window(object windowObject) {
            string caption = windowObject.GetType().InvokeMember("Caption", System.Reflection.BindingFlags.GetProperty, null, windowObject, null).ToString();
     
            // try to get the HWND ptr from the windowObject / could be an Inspector window or an explorer window
            _windowHandle = FindWindow("rctrl_renwnd32\0", caption);
        }
    }



    If you want to get the main HWnd of the Outlook process,
    get the Process of Outlook and use Process.Handle.


    Hope this helps,
    greets - Helmut

    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    • Marked as answer by Bessie Zhao Friday, September 18, 2009 10:37 AM
    Saturday, September 12, 2009 6:12 AM
    Answerer
  • If you want to get the main HWnd of the Outlook process,
    get the Process of Outlook and use Process.Handle.


    Hope this helps,
    greets - Helmut

    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    What should I do to get the process then?
    Saturday, September 12, 2009 4:59 PM
  • Hi,

    You could use the methods of System.Diagnostics.Process class[see: Process Class]. Here is the code snippet.

                Process[] prs = Process.GetProcessesByName("OUTLOOK");
                Process pr = prs[0];
                System.IntPtr hwnd2 = pr.Handle;
    Now we can get the handle of outlook。

    Hope this helps,
    Bessie
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, September 16, 2009 11:17 AM
  • Hi,

    While that will work, at best it is an incomplete approach because if there are multiple instances of Outlook running, there is no guarantee as to which instance will occupy the first element of the Process array.  Nor is there any simple way to disambiguate between the running instances.

    If this is a VSTO customization, you will want to use Process.GetCurrentProcess().  This will return the Process wrapper for the instance of Outlook that your code is running in.

    Sincerely,

    Geoff Darst
    Microsoft VSTO Team
    • Marked as answer by Bessie Zhao Friday, September 18, 2009 10:37 AM
    Wednesday, September 16, 2009 3:56 PM
    Answerer