如何在应用程序之上保持对话框

时间:2014-02-24 16:02:49

标签: c# .net outlook-addin

我目前正在开发一个小型的outlook-addin。我的插件打开一个对话框( System.Windows.Forms.Form )。

我希望将对话框放在outlook的顶部,所以我尝试了 TopMost ,但这使对话框保持在所有应用程序之上。

当Outlook是活跃的应用程序时,我希望对话框位于顶部,我该如何实现?

更新

感谢 Dmitry kallocain ,我可以解决这个问题。我想概述一下我得到的解决方案:

在我的Outlook插件的 TabCalendarRibbon 类中,我有一个用于激活对话框的事件方法,在那里我使用kallocain的代码来获取窗口句柄:

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

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

如kollacains的回答所述,我不得不添加OLE互操作程序集。我使用资源管理器句柄来显示我的对话框:

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

您可能会注意到,我无法直接使用窗口句柄,但必须实现一个实现 IWin32Window 的小包装器。为此,我按照我之前通过Dmitry链接的答案找到的描述。我只是复制了以下代码:

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

    public IntPtr Handle
    {
        get { return _hwnd; }
    }

    private IntPtr _hwnd;
}

瞧,它的功能与我预期的一样。如果只有我在日历功能区上,对话框才会激活会更好,但这是另一天的事情。顺便说一句,我认为结果的代码很多......

2 个答案:

答案 0 :(得分:2)

正如Akrem所说,请参阅How to make form topmost to the application only?。要获取Outlook资源管理器对象的HWND(例如Application.ActiveExplorer),请将其强制转换为IOleWindow并调用IOleWindow.GetWindow()。

答案 1 :(得分:1)

德米特里的回答是正确的。您只需要添加对“Microsoft.VisualStudio.OLE.Interop.dll”的引用(可以在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);
   }
}