我正在尝试在我的一个应用程序中实现一个简单的Web浏览器控件。这是为了帮助将Web应用程序集成到我正在创建的工具集中。
问题是,此Web应用程序绝对喜欢弹出窗口…。
打开弹出窗口后,它将在IE窗口中打开,该窗口不是我的主窗口所在的MDI容器表单的子窗口。
如何获得通过单击WebBrowser中的链接作为MDI容器的子级而创建的所有弹出窗口(类似于设置表单的MDIParent属性)?
提前致谢。
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弹出窗口,也不使用浏览器窗口来显示它,因此您无法截取或替换它。