一尘不染

如何在我创建的另一个窗口中显示来自WebBrowser的弹出窗口?

c#

我正在尝试在我的一个应用程序中实现一个简单的Web浏览器控件。这是为了帮助将Web应用程序集成到我正在创建的工具集中。

问题是,此Web应用程序绝对喜欢弹出窗口…。

打开弹出窗口后,它将在IE窗口中打开,该窗口不是我的主窗口所在的MDI容器表单的子窗口。

如何获得通过单击WebBrowser中的链接作为MDI容器的子级而创建的所有弹出窗口(类似于设置表单的MDIParent属性)?

提前致谢。


阅读 414

收藏
2020-05-19

共1个答案

一尘不染

Web浏览器控件支持NewWindow事件以获取有关弹出窗口的通知。但是,Winforms包装器不允许您做很多事情,只能取消弹出窗口。本机COM包装程序允许传递回Web浏览器的新实例,然后该实例将用于显示弹出窗口。

利用这一点需要做一些工作。对于初学者,请使用“项目+添加引用”的“浏览”选项卡,然后选择c:\ windows \ system32 \
shdocvw.dll。这就增加了对本机COM接口的引用。

创建一个充当弹出窗体的窗体。将WebBrowser放到它上面,并使它的代码类似于以下内容:

public partial class Form2 : Form {
    public Form2() {
        InitializeComponent();
    }
    public WebBrowser Browser {
        get { return webBrowser1; }
    }
}

Browser属性提供对浏览器的访问,该浏览器将用于在弹出窗口中显示网页。

现在回到主要形式。将WebBrowser放到它上面,并使它的代码如下所示:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        webBrowser1.Url = new Uri("http://google.com");
    }
    SHDocVw.WebBrowser nativeBrowser;
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        nativeBrowser = (SHDocVw.WebBrowser)webBrowser1.ActiveXInstance;
        nativeBrowser.NewWindow2 += nativeBrowser_NewWindow2;
    }
    protected override void OnFormClosing(FormClosingEventArgs e) {
        nativeBrowser.NewWindow2 -= nativeBrowser_NewWindow2;
        base.OnFormClosing(e);
    }

    void nativeBrowser_NewWindow2(ref object ppDisp, ref bool Cancel) {
        var popup = new Form2();
        popup.Show(this);
        ppDisp = popup.Browser.ActiveXInstance;
    }
}

OnLoad方法获取对本机COM接口的引用,然后将事件处理程序订阅到NewWindow2事件。我确保在FormClosing事件处理程序中取消订阅该事件,而不是100%确定是否必要。更好的安全后悔。

NewWindow2事件处理程序是症结所在,请注意,第一个参数允许传回无类型的引用。那应该是弹出窗口中的本机浏览器。因此,我创建了一个Form2实例并对其进行Show()。注意Show()的参数,该参数确保弹出窗口是一个拥有的窗口。对于您的应用程序,将其替换为必需的,假设您要创建一个MDI子窗口。

请注意,当Javascript使用alert()时,此事件不会针对显示的窗口触发。浏览器不会将该窗口视为HTML弹出窗口,也不使用浏览器窗口来显示它,因此您无法截取或替换它。

2020-05-19