如何在应用程序顶部保留对话框



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

我想让对话框位于outlook的顶部,所以我尝试了TopMost,但这会让对话框位于所有应用程序的顶部。

当outlook是活动应用程序时,我希望对话框位于顶部,我如何实现这一点?

更新

多亏了Dmitrykallocain我才能解决这个问题。我想概述一下我的解决方案:

在我的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));

正如您可能注意到的,我不能直接使用窗口句柄,但必须实现一个实现IWin32Windows的小型包装器。为此,我遵循了我通过Dmitry链接到的上一个答案找到的描述。我只是复制了以下代码:

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

瞧,它的效果和我预想的差不多。如果对话框只有在我在日历功能区时才处于活动状态,那会更好,但这是另一天的事情。顺便说一句,我认为结果的大部分代码。。。

正如Akrem所指出的,请参阅如何使表单仅位于应用程序的最顶层?。要获取Outlook资源管理器对象(例如Application.ActiveExplorer)的HWND,请将其强制转换为IOleWindow并调用IOleWindow.GetWindow().

Dmitry的回答是正确的。您只需添加对"Microsoft.VisualStudio.OLE.Interop.dll"的引用(可以在C:\Program Files(x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssembly中找到)。
Explorer explorer = control.Context as Explorer;
if (explorer != null)
{
IOleWindow window = explorer as IOleWindow;
if (window != null)
{
IntPtr explorerHandle;
window.GetWindow(out explorerHandle);
}
}

最新更新