进行webBrower开发的时候,肯定都会遇到一个问题。 那就是怎么样强制在本窗口打开新窗口的问题。 网上最常见的解决方法就是, 在NewWindow事件中取得要打开的网址,取消打开新窗口,然后在本窗口打开要转向的网址 p rivate void webBrowser_1_NewWindow(object sender, CancelEventArgs e) { WebBrowser webBrowser_temp = (WebBrowser)sender; string newUrl = webBrowser_temp.Document.ActiveElement.GetAttribute("href"); webBrowser_1.Url = new Uri(newUrl); e.Cancel = true; }
虽然这种方法能够解决大部分的要求,但是治标不治本。 而且当网址里面还有汉字的时候就更加麻烦了,比如在百度MP3,歌曲名字都是汉字,和百度空间里面,大部分用户名都是汉字,所以取的网址都用乱码。虽然,可以对网址进行编码,但是并不是所有网页都是uft-8编码,对于如何得知网页的编码又是一个课题了。
最根本的方法就是重写了。 新建一个类 using System; using System.Collections.Generic; using System.Text;
namespace webTestRecorder {
public class ExtendedWebBrowser : System.Windows.Forms.WebBrowser { System.Windows.Forms.AxHost.ConnectionPointCookie cookie; WebBrowserExtendedEvents events;
//This method will be called to give you a chance to create your own event sink protected override void CreateSink() { //MAKE SURE TO CALL THE BASE or the normal events won't fire base.CreateSink(); events = new WebBrowserExtendedEvents(this); cookie = new System.Windows.Forms.AxHost.ConnectionPointCookie(this.ActiveXInstance, events, typeof(DWebBrowserEvents2)); }
protected override void DetachSink() { if (null != cookie) { cookie.Disconnect(); cookie = null; } base.DetachSink(); }
//This new event will fire when the page is navigating public event EventHandler<WebBrowserExtendedNavigatingEventArgs> BeforeNavigate; public event EventHandler<WebBrowserExtendedNavigatingEventArgs> BeforeNewWindow;
protected void OnBeforeNewWindow(string url, out bool cancel) { EventHandler<WebBrowserExtendedNavigatingEventArgs> h = BeforeNewWindow; WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, null); if (null != h) { h(this, args); } cancel = args.Cancel; }
protected void OnBeforeNavigate(string url, string frame, out bool cancel) { EventHandler<WebBrowserExtendedNavigatingEventArgs> h = BeforeNavigate; WebBrowserExtendedNavigatingEventArgs args = new WebBrowserExtendedNavigatingEventArgs(url, frame); if (null != h) { h(this, args); } //Pass the cancellation chosen back out to the events cancel = args.Cancel; } //This class will capture events from the WebBrowser class WebBrowserExtendedEvents : System.Runtime.InteropServices.StandardOleMarshalObject, DWebBrowserEvents2 { ExtendedWebBrowser _Browser; public WebBrowserExtendedEvents(ExtendedWebBrowser browser) { _Browser = browser; }
//Implement whichever events you wish public void BeforeNavigate2(object pDisp, ref object URL, ref object flags, ref object targetFrameName, ref object postData, ref object headers, ref bool cancel) { _Browser.OnBeforeNavigate((string)URL, (string)targetFrameName, out cancel); }
public void NewWindow3(object pDisp, ref bool cancel, ref object flags, ref object URLContext, ref object URL) { _Browser.OnBeforeNewWindow((string)URL, out cancel); }
} [System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch), System.Runtime.InteropServices.TypeLibType(System.Runtime.InteropServices.TypeLibTypeFlags.FHidden)] public interface DWebBrowserEvents2 {
[System.Runtime.InteropServices.DispId(250)] void BeforeNavigate2( [System.Runtime.InteropServices.In, System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.IDispatch)] object pDisp, [System.Runtime.InteropServices.In] ref object URL, [System.Runtime.InteropServices.In] ref object flags, [System.Runtime.InteropServices.In] ref object targetFrameName, [System.Runtime.InteropServices.In] ref object postData, [System.Runtime.InteropServices.In] ref object headers, [System.Runtime.InteropServices.In, System.Runtime.InteropServices.Out] ref bool cancel); [System.Runtime.InteropServices.DispId(273)] void NewWindow3( [System.Runtime.InteropServices.In, System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.IDispatch)] object pDisp, [System.Runtime.InteropServices.In, System.Runtime.InteropServices.Out] ref bool cancel, [System.Runtime.InteropServices.In] ref object flags, [System.Runtime.InteropServices.In] ref object URLContext, [System.Runtime.InteropServices.In] ref object URL);
} }
public class WebBrowserExtendedNavigatingEventArgs : System.ComponentModel.CancelEventArgs { p rivate string _Url; public string Url { get { return _Url; } }
p rivate string _Frame; public string Frame { get { return _Frame; } }
public WebBrowserExtendedNavigatingEventArgs(string url, string frame) : base() { _Url = url; _Frame = frame; } } }
然后把webBrowser换成我们重写的ExtendedWebBrowser,添加事件处理 ieBrowser = new ExtendedWebBrowser(); ieBrowser.BeforeNewWindow += new EventHandler<WebBrowserExtendedNavigatingEventArgs>(ieBrowser_BeforeNewWindow);
然后在其BeforeNewWindow事件中:
void ieBrowser_BeforeNewWindow(object sender, WebBrowserExtendedNavigatingEventArgs e) { e.Cancel=true; ((ExtendedWebBrowser)sender).Navigate(e.Url); }
---------------------另一方案下下----------------------
要解决这个问题,可以使用下面的方法:
在日常的开发中,大家有时需要用WebBrowser加载URL,来实现某些功能。而这时,我们就不希望所打开的页面中的链接,在新窗口中打开,因为这样的话,实际上是用系统默认的浏览器打开了,从而脱离了你的WebBrowser,也就不能被你所控制了。
假设WebBrowser的Name是 webBrowser1
******* void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{ //将所有的链接的目标,指向本窗体
foreach (HtmlElement archor in this.webBrowser1.Document.Links)
{
archor.SetAttribute("target", "_self");
} //将所有的FORM的提交目标,指向本窗体 foreach (HtmlElement form in this.webBrowser1.Document.Forms){ form.SetAttribute("target", "_self"); }}
******* void webBrowser1_NewWindow(object sender, CancelEventArgs e){ e.Cancel = true;}
记得将 WebBrowser 的 AllowWebBrowserDrop 设为 false
将 WebBrowser 的 WebBrowserShortcutsEnabled 设为 false
将 WebBrowser 的 IsWebBrowserContextMenuEnabled 设为 false
|