WebBrowser控件应用:弹出新窗体和关闭窗口

原文: WebBrowser控件应用:弹出新窗体和关闭窗口

 

缘起:上次写了一个《WebBrowser控件的简单应用2》,提到了在NewWindow事件中打开新窗口的例子。有网友“队长 提出那个事件得到的参数是本页面的,而不是新页面的,经过测试,果然url参数不是新页面的。

Open新页面要处理的:<?xml:namespace prefix="o" ns="urn:schemas-microsoft-com:office:office"?>

1<<a href=’xxxxx’ target=’_blank’>>; 
     2: οnclick=’window.open’ ;

3:引用js文件

4ClientScript.RegisterStartupScript();等。

5:还有要实现在打开的页面里能用window.opener对象

Close要处理的:

1οnclick=’window.close ;

2:引用js文件

3ClientScript.RegisterStartupScript()等。

 

经过在网上搜索,结果并不令人满意。基本上,WebBrowser控件不提供这个(将要打开的新页面的地址)功能,只能通过其他方法。

这里介绍一下网上的一个简单的解决方案、我的一个简单方案、微软的回答、一个终极解决方法。

 

网上现在有人给出这样的一个解决方案:在_NewWindow事件通过wb_Container.StatusText来获得当前将要打开的页面。代码可以这样写:

        private void wb_Container_NewWindow(object sender, CancelEventArgs e)

        {

            e.Cancel = true;

             string newURL = wb_Container.StatusText;

            //'open

           

        }

我测试了一下,这样做基本上只能处理<a href=’xxxxx’ target=’_blank’>的这种情况。对于<button>里面的onlcick事件window.open()毫无作用。

原因很简单,他只是利用了WebBrower现实Status的特点来做,不全面,不安全。至于其他情况也是完全不能处理,比如js中使用window.Open,这个方案根本不能检查。

 

我的处理方法

刚开始,我使用了这样的思路:针对所有可能出现的情况,找个各个不同方法来处理。

比如说,对于<a herf=’’的这种情况,就用wb_Container.StatusText方法,但是要加入一个判断。If(wb_Container.StatusText!=””)。对于window.openRegisterStartupScript的,可以通过替换js来实现。

本来的window.open函数,在程序完成加载之后,我把这个函数修改成window.external.open

然后,我把我的AppBrowser类里面加入几个publicOpen函数来对应原来的jsopen函数就可以了。

这是一个代码实现。

private void wb_Container_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)

        {

            //for windows.open

            if (wb_Container.DocumentText.IndexOf("window.open(") > -1 || wb_Container.DocumentText.IndexOf("window.close()") > -1)

            {

                wb_Container.DocumentText = wb_Container.DocumentText.Replace("window.open(", "window.external.open(").Replace("window.close()", "window.external.close()");

            }

        }

这样处理之后,保证了我的浏览器也能理解这些js

这个方案唯一不能处理的就是js文件里面有处理的情况。

还有一个小问题,替换之后的document对象的action变化了。这个可以通过方法来实现,就是替换上边的函数,改用递归document.all来实现,检查每个element控件的内容来实现。

但是,毕竟美中不足。

 

微软的解释是这样的:这个问题,下一个版本在解决(http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115195),开发者可以通过扩展WebBrower及其Event来实现。并且提供了一个简单的代码(但是显示不完全)。是的,这是个好的解决方案,但不是我想要的。既然封装了这个控件,为什么不提供这么重要的一个参数呢?

 

有高手已经做出了一个模型:(http://www.codeproject.com/csharp/ExtendedWebBrowser.asp

(作者实现了一个类似IE7效果的浏览器
Article.gif

这个模型里面,作者自己封装并且扩展了这个控件,是个最终极的解决方法。

主要思路:提供了一个将要打开新窗口的事件,并且提供更多的参数。这些参数来自IWebBrowser2等接口,还提供了一些WndProc重载来实现window.close

下载之后,我保留了这些类,做了一个简单的测试

ExtendedWebBrowser : System.Windows.Forms.WebBrowser

   .WebBrowserExtendedEvents : UnsafeNativeMethods.DWebBrowserEvents2

   .WindowsMessages(enum)

UnsafeNativeMethods

   .DWebBrowserEvents2([ComImport, TypeLibType((short)0x1010), InterfaceType((short)2), Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D")])

   .IWebBrowser2([ComImport, SuppressUnmanagedCodeSecurity, TypeLibType(TypeLibTypeFlags.FOleAutomation | (TypeLibTypeFlags.FDual | TypeLibTypeFlags.FHidden)), Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E")])

BrowserExtendedNavigatingEventArgs : CancelEventArgs

UrlContext

ScriptError

NativeMethods

结果非常不错。

主要处理的几个地方:

NewWindow2NewWindow3:处理新打开窗口

BeforeNavigate2:获得将要打开的窗口的地址。

主要提供的新事件:_StartNewWindow(object sender, BrowserExtendedNavigatingEventArgs e)

 

下边这一个是我的第二个AppBrowser类,使用上边封装扩展之后的WebBrower控件。

 

ContractedBlock.gif ExpandedBlockStart.gif AppBrowser2 source code
  1None.gif    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
  2None.gif    public partial class AppBrowser2 : Form
  3ExpandedBlockStart.gifContractedBlock.gif    dot.gif{
  4ContractedSubBlock.gifExpandedSubBlockStart.gif        property#region property
  5InBlock.gif        private string _url;
  6InBlock.gif        public string URL
  7ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
  8ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn _url; }
  9ExpandedSubBlockStart.gifContractedSubBlock.gif            set dot.gifthis._url = value; }
 10ExpandedSubBlockEnd.gif        }

 11InBlock.gif
 12InBlock.gif        private ExtendedWebBrowser _browser;
 13InBlock.gif        // Allows other code to obtain a reference to the extended web browser component
 14InBlock.gif        private ExtendedWebBrowser WebBrowser
 15ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 16ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn _browser; }
 17ExpandedSubBlockEnd.gif        }

 18ExpandedSubBlockEnd.gif        #endregion

 19ContractedSubBlock.gifExpandedSubBlockStart.gif        cons.#region cons.
 20InBlock.gif        public AppBrowser2()
 21ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 22InBlock.gif            InitializeComponent();
 23ExpandedSubBlockEnd.gif        }

 24InBlock.gif        public AppBrowser2(string url)
 25ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 26InBlock.gif            InitializeComponent();
 27InBlock.gif            _browser = new ExtendedWebBrowser();
 28InBlock.gif            _browser.Dock = DockStyle.Fill;
 29InBlock.gif            _browser.DownloadComplete += new EventHandler(_browser_DownloadComplete);
 30InBlock.gif            _browser.Navigated += new WebBrowserNavigatedEventHandler(_browser_Navigated);
 31InBlock.gif            _browser.StartNewWindow += new EventHandler<BrowserExtendedNavigatingEventArgs>(_browser_StartNewWindow);//get js:window.open or <a href event
 32InBlock.gif            _browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(_browser_DocumentCompleted);
 33InBlock.gif            _browser.StatusTextChanged += new EventHandler(_browser_StatusTextChanged);
 34InBlock.gif            _browser.Quit += new EventHandler(_browser_Quit);//get js:window.close event
 35InBlock.gif            this.pnl_container.Controls.Add(_browser);
 36InBlock.gif            this.URL = url;
 37InBlock.gif            _browser.Navigate(URL);
 38InBlock.gif            _browser.ObjectForScripting = this;//set this to be the COM handler
 39ExpandedSubBlockEnd.gif        }
 
 40ExpandedSubBlockEnd.gif        #endregion

 41InBlock.gif 
 42ContractedSubBlock.gifExpandedSubBlockStart.gif        window : close and open#region window : close and open
 43InBlock.gif        void _browser_Quit(object sender, EventArgs e)
 44ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 45InBlock.gif            this.Close();
 46ExpandedSubBlockEnd.gif        }

 47InBlock.gif
 48InBlock.gif        void _browser_StartNewWindow(object sender, BrowserExtendedNavigatingEventArgs e)
 49ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 50InBlock.gif            AppBrowser2 ab2 = new AppBrowser2(e.Url.ToString());
 51InBlock.gif            e.AutomationObject = ab2.WebBrowser.Application;//for 'window.opener'  
 52InBlock.gif            ab2.Show();
 53ExpandedSubBlockEnd.gif        }
 
 54ExpandedSubBlockEnd.gif        #endregion

 55ContractedSubBlock.gifExpandedSubBlockStart.gif        other browser event#region other browser event
 56InBlock.gif        void Window_Error(object sender, HtmlElementErrorEventArgs e)
 57ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 58InBlock.gif            // We got a script error, record it
 59InBlock.gif            //ScriptErrorManager.Instance.RegisterScriptError(e.Url, e.Description, e.LineNumber);
 60InBlock.gif            // Let the browser know we handled this error.
 61InBlock.gif            e.Handled = true;
 62ExpandedSubBlockEnd.gif        }

 63InBlock.gif        void _browser_DownloadComplete(object sender, EventArgs e)
 64ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 65InBlock.gif            // Check wheter the document is available (it should be)
 66InBlock.gif            if (this.WebBrowser.Document != null)
 67ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 68InBlock.gif                // Subscribe to the Error event
 69InBlock.gif                this.WebBrowser.Document.Window.Error += new HtmlElementErrorEventHandler(Window_Error);
 70InBlock.gif                UpdateAddressBox();
 71ExpandedSubBlockEnd.gif            }

 72ExpandedSubBlockEnd.gif        }

 73InBlock.gif        void _browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
 74ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 75InBlock.gif            UpdateAddressBox();
 76ExpandedSubBlockEnd.gif        }

 77InBlock.gif        void _browser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
 78ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 79InBlock.gif            UpdateAddressBox();
 80ExpandedSubBlockEnd.gif        }

 81InBlock.gif
 82InBlock.gif        void _browser_StatusTextChanged(object sender, EventArgs e)
 83ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 84InBlock.gif            this.toolStripStatusState.Text = WebBrowser.StatusText;
 85ExpandedSubBlockEnd.gif        }

 86InBlock.gif        // Updates the info on the window
 87InBlock.gif        private void UpdateAddressBox()
 88ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 89InBlock.gif            this.toolStripStatusTitle.Text = this.WebBrowser.Document.Title;
 90ExpandedSubBlockEnd.gif        }

 91ExpandedSubBlockEnd.gif        #endregion

 92InBlock.gif
 93ContractedSubBlock.gifExpandedSubBlockStart.gif        external function for js#region external function for js
 94ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 95InBlock.gif        /// this function can be invoked by js in html
 96InBlock.gif        /// like this 'javascript:window.external.ShowMessage('this is invoke from web');'
 97InBlock.gif        /// </summary>
 98ExpandedSubBlockEnd.gif        /// <param name="msg"></param>

 99InBlock.gif        public void ShowMessage(string msg)
100ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
101InBlock.gif            MessageBox.Show(msg, "alert");
102ExpandedSubBlockEnd.gif        }

103InBlock.gif
104ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
105InBlock.gif        /// open new, for JS: window.open
106InBlock.gif        /// </summary>
107ExpandedSubBlockEnd.gif        /// <param name="url"></param>

108InBlock.gif        public void Open(string url)
109ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
110InBlock.gif            AppBrowser2 newAB2 = new AppBrowser2(url);
111InBlock.gif            newAB2.Show();
112ExpandedSubBlockEnd.gif        }
 
113ExpandedSubBlockEnd.gif        #endregion

114ExpandedBlockEnd.gif    }
posted on 2014-06-14 13:20 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3788161.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值