我被要求改装一个围绕IE 9控件构建的自定义网络浏览器。其中一个要求是必须捕获所有弹出窗口并将其重定向到新选项卡。客户不希望出现任何浮动的独立窗口。
之前的开发人员实现了以下功能来捕获这些情况并改为打开一个新选项卡。
public void NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
{
BrowserExtendedNavigatingEventArgs args = new BrowserExtendedNavigatingEventArgs(ppDisp, new Uri(bstrUrl), null, (UrlContext)dwFlags);
_Browser.OnStartNewWindow(args);
Cancel = args.Cancel;
ppDisp = args.AutomationObject;
}
当其中一个打开的窗口希望能够从javascript调用window.close时,会出现问题。
我希望我可以使用这个功能
public void WindowClosing(bool isChildWindow, ref bool cancel)
检测javascript调用并关闭选项卡。但是从不调用此函数。 javascript函数本身似乎有效。选项卡的内容已清除。如何检测此方案并关闭选项卡?
请注意,IE9 active x控件并不是一项硬性要求。但请不要建议我仅仅为了互联网的纯度而切换渲染引擎:P。
编辑:
这是我在C#中对DWebBrowserEvents2接口的定义。
[ComImport, TypeLibType((short)0x1010), InterfaceType((short)2), Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D")]
public interface DWebBrowserEvents2
{
[DispId(0x111)]
void NewWindow3(
[In, Out, MarshalAs(UnmanagedType.IDispatch)] ref object ppDisp,
[In, Out] ref bool Cancel,
[In] uint dwFlags,
[In, MarshalAs(UnmanagedType.BStr)] string bstrUrlContext,
[In, MarshalAs(UnmanagedType.BStr)] string bstrUrl);
[DispId(253)]
void OnQuit();
[DispId(263)]
void WindowClosing(
[In] bool isChildWindow,
[In, Out] ref bool cancel);
[DispId(283)]
void WindowStateChanged(
[In] uint dwFlags,
[In] uint dwVAlidFlagsMask);
[DispId(271)]
void NavigateError(
[In, MarshalAs(UnmanagedType.IDispatch)] object pDisp,
[In] ref object URL, [In] ref object frame,
[In] ref object statusCode, [In, Out] ref bool cancel);
}
答案 0 :(得分:4)
在这里找到答案:http://social.msdn.microsoft.com/Forums/en/winforms/thread/1cda7799-bf65-4c66-a3bf-488656998191它对我有用。
如果该链接消失,这是该页面的答案:
// A delegate type for hooking up close notifications.
public delegate void ClosingEventHandler(object sender, EventArgs e);
// We need to extend the basic Web Browser because when a web page calls
// "window.close()" the containing window isn't closed.
public class ExtendedWebBrowser : WebBrowser
{
// Define constants from winuser.h
private const int WM_PARENTNOTIFY = 0x210;
private const int WM_DESTROY = 2;
public event ClosingEventHandler Closing;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_PARENTNOTIFY:
if (!DesignMode)
{
if (m.WParam.ToInt32() == WM_DESTROY)
{
Closing(this, EventArgs.Empty);
}
}
DefWndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
}
//Then your containing class has the following:
private ExtendedWebBrowser browserControl;
this.browserControl.Closing +=new ClosingEventHandler(browserControl_Closing);
private void browserControl_Closing(object sender, EventArgs e)
{
this.Close();
}