WebBrowser弹出窗口之(一) -- window.open( )

1. 对于新打开的窗口,在打开时会触发WebBrowser的NewWindow3事件,触发该事件有以下几种操作:
1) 按住SHIFT或CTRL键时点击鼠标;
2) 在链接的右键菜单中选择“在新窗口中打开”或“在新标签中打工”;
3) 链接的目标窗口不存在或者为“_blank“;
4) Javascript的windows.open函数调用;
5) 在调用NavigateNavigate2 时,设置了navOpenInNewWindow标志位;
在自定义的窗口中使用WebBrowser控件时,可以捕捉该事件,然后创建新的窗口,在窗口中打开指定的链接;但.NET实现的WebBrowser控件没有给出该事件的接口,我们需要扩展该控件。

STEP 1:定义扩展的WebBrowser控件

public class ExWebBrowser : System.Windows.Forms.WebBrowser
{ // ……
}

STEP 2: 定义浏览器窗口类:
窗口中有一个ExtWebBrowser控件browser,然后一个地址栏输入框txtURL,一个用于打开页面的按钮btnGo。

public partial class ExWebBrowserForm : Form
{
    public ExWebBrowserForm( )
    {
        InitializeComponent( );
    }

    public ExWebBrowser Browser
    {
        get { return null; }
    }

    private void btnGo_Click(object sender, EventArgs e)
    {
        try {
            _browser.Navigate(txtURL.Text);
        } catch (Exception ex) {
            MessageBox.Show(ex.ToString( ), ex.Message);
        }
    }
}

STEP 3:定义要实现的事件接口
还有其它事件,可以在此处定义,但我们目前只关注NewWindow3一个事件,必要时在该接口中增加即可。
[ComImport, TypeLibType((short)0x1010), InterfaceType((short)2), Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D")]
public interface IWebBrowserEvents2
{
    [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), 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);
}

STEP 4:实现事件接口
在捕捉到NewWindow3事件后创建一个新的窗口,然后在新窗口的ExWebBrowser控件中打开指定的页面。

class WebBrowserExtendedEvents : IWebBrowserEvents2
{
        private ExWebBrowser _browser = null;

        public WebBrowserExtendedEvents(ExWebBrowser browser) { _browser = browser; }

        private object PopupWindow( )
        {
                ExWebBrowserForm form = new ExWebBrowserForm( );
                form.Text += " -- " + form.Browser.Url ?? string.Empty;
                form.Visible = true;
                form.Show( );
                return form.Browser.ApplicationObject;
       }
        // NewWindow3 event, used on Windows XP SP2 and higher
        public void NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
        {
            Cancel = _browser.DisablePopupWindow;
            if (!Cancel)
                ppDisp = PopupWindow( ) ;
        }
}

STEP 5:为ExWebBrowser附件实现的IWebBrowserEvents2接口
此处增加了一个属性DisablePopupWindow,该属性用于控制是否禁止弹出窗口。

public class ExWebBrowser : System.Windows.Forms.WebBrowser
{
    private IWebBrowser2 axIWebBrowser2;
    private bool _diablePopupWindow = false;
    private WebBrowserExtendedEvents events = null;
    private System.Windows.Forms.AxHost.ConnectionPointCookie cookie;

    public bool DisablePopupWindow
    {
        get { return _diablePopupWindow; }
        set { _diablePopupWindow = value; }
    }

    // 该方法由系统自动调用,从该函数的调用中截获到IWebBrowser2接口
    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void AttachInterfaces(object nativeActiveXObject)
    {
        this.axIWebBrowser2 = (IWebBrowser2)nativeActiveXObject;
        base.AttachInterfaces(nativeActiveXObject);
    }

    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void DetachInterfaces( )
    {
        this.axIWebBrowser2 = null;
        base.DetachInterfaces( );
    }

  // 返回WebBrowser的自动化对象   
   public object ApplicationObject
    {
        get { return axIWebBrowser2.Application; }
    }

  // 此方法增加自定义的事件对象  
   [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void CreateSink( )
    {
        //  一定在此调用基类的方法,否则WebBrowser自己实现的事件就不能触发了
        base.CreateSink( );
        events = new WebBrowserExtendedEvents(this);
        cookie = new AxHost.ConnectionPointCookie(this.ActiveXInstance, events, typeof(IWebBrowserEvents2));
    }

    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void DetachSink( )
    {
        if (null != cookie) {
            cookie.Disconnect( );
            cookie = null;
        }
    }
}
STEP 6:主程序
主程序很简单,就是创建一个浏览器窗口。由于我是在现有的一个工程中写的主函数,基于控制台的,如果创建windows程序在主程序中使用Application.Run(new ExWebBrowserForm() )就可以了。
class Program
    {
        [STAThread]
        static int Main(string[] args)
        {
            ExWebBrowserForm browser = new ExWebBrowserForm( );
            browser.ShowDialog( );
         }
}

其实,原理很简单,因为.NET Framework中实现WebBrowser时,很多IE的事件或方法都没有定义出来,需要时只能通过AttachInterfaces把相应的接口附上,通过这个方法,我们就可以有选择性地对我们关心的接口进行实现。

我们一旦获取了一个包含子窗口的WebBrowser控件,就可以在程序中通过该控件进行任何自动化的操作了。

但对于showModalDialog( )和showModelessDialog( )弹出是就没有NewWindow3事件了,下一篇中再讨论这两个窗口的弹出问题。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值