我目前正在开发一个小的outlook插件。我的插件打开一个对话框(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));
正如您可能注意到的,我不能直接使用窗口句柄,但必须实现一个实现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().
Explorer explorer = control.Context as Explorer;
if (explorer != null)
{
IOleWindow window = explorer as IOleWindow;
if (window != null)
{
IntPtr explorerHandle;
window.GetWindow(out explorerHandle);
}
}