English 中文(简体)
当从IE BHO打开对话框时,如何确保对话框是模态的?
原标题:
  • 时间:2008-09-24 12:50:31
  •  标签:

我有一个使用C#编写的Internet Explorer浏览器小助手对象(BHO),在各个地方我以模态对话框形式打开表单。有时这有效果,但在某些情况下不起作用。目前我可以复制的情况是,当IE正在运行JavaScript以打开其他子窗口时......我猜它在某个地方有点混淆....

The problem is that when I call:

(new MyForm(someParam)).ShowDialog();

the form is not modal, so I can click on the IE window and it gets focus. Since IE is in the middle of running my code it doesn t refresh and therefore to the user it appears that IE is hanging.

Is there a way of ensuring that the form will be opened as modal, ie that it s not possible for the form to be hidden behind IE windows.

(I m using IE7.)

NB: this is a similar question to this post although that s using java. I guess the solution is around correctly passing in the IWin32Window of the IE window, so I m looking into that.

最佳回答

It wasn t my intention to answer my own question, but...

It seems that if you pass in the correct IWin32Window to the ShowDialog() method it works fine. The trick is how to get this. Here s how I did this, where siteObject is the object passed in to the SetSite() method of the BHO:

IWebBrowser2 browser = siteObject as IWebBrowser2;
if (browser != null) hwnd = new IntPtr(browser.HWND);
(new MyForm(someParam)).ShowDialog(new WindowWrapper(hwnd));

...

// Wrapper class so that we can return an IWin32Window given a hwnd
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
    public WindowWrapper(IntPtr handle)
    {
        _hwnd = handle;
    }

    public IntPtr Handle
    {
        get { return _hwnd; }
    }

    private IntPtr _hwnd;
}

Thanks to Ryan for the WindowWrapper class, although I d hoped there was a built-in way to do this?

UPDATE: this won t work on IE8 with Protected Mode, since it s accessing an HWND outside what it should be. Instead you ll have to use the HWND of the current tab (or some other solution?), e.g. see .net example in this post for a way of getting that.

问题回答

Here s a more concise version of Ryan/Rory s WindowWrapper code:

internal class WindowWrapper : IWin32Window
{
    public IntPtr Handle { get; private set; }
    public WindowWrapper(IntPtr hwnd) { Handle = hwnd; }
}




相关问题
热门标签