anhoppe
anhoppe

Reputation: 4507

How to keep a dialog on top of application

I'm currently working on a little outlook-addin. My plugin opens a dialog (System.Windows.Forms.Form).

I'd like to keep the dialog on top of outlook, so I tried the TopMost, but that keeps the dialog on top of all applications.

I'd like the dialog to be on top when outlook is the active application, how can I achieve this?

UPDATE

Thanks to Dmitry and kallocain I could solve this issue. I want to outline my resulting solution:

In the TabCalendarRibbon class of my Outlook plugin I have an event method for activating my dialog, there I used the code from kallocain to get the window handle:

Explorer explorer = Context as Explorer;
IntPtr explorerHandle = (IntPtr)0;

if (explorer != null)
{
    IOleWindow window = explorer as IOleWindow;
    if (window != null)
    {
        window.GetWindow(out explorerHandle);
    }
}

As described in kollacains answer, I had to add the OLE interop assembly. I used the explorer handle to Show my dialog:

var dlg = new NewEntryDialog();
dlg.Show(new WindowWrapper(explorerHandle));

As you might notice, I could not use the window handle directly but had to implement a tiny wrapper that implements IWin32Window. For this I followed a description I found via the previous answer Dmitry linked to. I simply copied the following code:

public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    public WindowWrapper(IntPtr handle)
    {
        _hwnd = handle;
    }

    public IntPtr Handle
    {
        get { return _hwnd; }
    }

    private IntPtr _hwnd;
}

And voila, it works pretty much as I expected. It would be even better if the dialog was only active as long as I am on the calendar ribbon, but that is something for another day. BTW, pretty much code for the result, I think...

Upvotes: 0

Views: 890

Answers (2)

Thomas Hetzer
Thomas Hetzer

Reputation: 1637

Dmitry answer is correct. You just have to add a reference to "Microsoft.VisualStudio.OLE.Interop.dll" (can be found in C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies).

Explorer explorer = control.Context as Explorer;
if (explorer != null)
{
   IOleWindow window = explorer as IOleWindow;
   if (window != null)
   {
      IntPtr explorerHandle;
      window.GetWindow(out explorerHandle);
   }
}

Upvotes: 1

Dmitry Streblechenko
Dmitry Streblechenko

Reputation: 66316

As Akrem noted, see How to make form topmost to the application only?. To get the HWND of an Outlook explorer object (e.g. Application.ActiveExplorer), cast it to IOleWindow and call IOleWindow.GetWindow().

Upvotes: 2

Related Questions