I have an outlook plugin which pops up a WPF window
Is there a way to set the WPF\'s Window.Owner
property to Outlook?
This can be done via WindowInteropHelper:
WindowInteropHelper wih = new WindowInteropHelper(yourWindow);
wih.Owner = outlookHwnd;
yourWindow.Show();
Kudos to @reedcopsey for putting us on the right track...
The trick for retrieving the Outlook Handle is using reflection to obtain the active window's title (Caption) and the FindWindow
Win32 API to obtain the active window IntPtr
handle (inspector, explorer, etc.). Inspired from this MSDN forum post. Once you have the active window handle, you can leverage WindowInteropHelper for managing the owner relationship.
ActiveWindow
)Window yourWPFWindow = new Window();
dynamic activeWindow = Globals.ThisAddIn.Application.ActiveWindow();
IntPtr outlookHwnd = new OfficeWin32Window(activeWindow).Handle;
WindowInteropHelper wih = new WindowInteropHelper(yourWPFWindow);
wih.Owner = outlookHwnd;
yourWPFWindow.Show();
///<summary>
/// This class retrieves the IWin32Window from the current active Office window.
/// This could be used to set the parent for Windows Forms and MessageBoxes.
///</summary>
///<example>
/// OfficeWin32Window parentWindow = new OfficeWin32Window (ThisAddIn.OutlookApplication.ActiveWindow ());
/// MessageBox.Show (parentWindow, "This MessageBox doesn't go behind Outlook !!!", "Attention !", MessageBoxButtons.Ok , MessageBoxIcon.Question );
///</example>
public class OfficeWin32Window : 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>OfficeWin32Window</b> class could be used to get the parent IWin32Window for Windows.Forms and MessageBoxes.
///</summary>
///<param name="windowObject">The current WindowObject.</param>
public OfficeWin32Window(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);
}
}