缘起:上次写了一个《WebBrowser控件的简单应用2》,提到了在NewWindow事件中打开新窗口的例子。有网友“队长 ”提出那个事件得到的参数是本页面的,而不是新页面的,经过测试,果然url参数不是新页面的。
Open新页面要处理的:
1:;
2: onclick=’window.open’ ;
3:引用js文件 ;
4:ClientScript.RegisterStartupScript();等。
5:还有要实现在打开的页面里能用window.opener对象
Close要处理的:
1:onclick=’window.close ;
2:引用js文件 ;
3:ClientScript.RegisterStartupScript()等。
经过在网上搜索,结果并不令人满意。基本上,WebBro
缘起:上次写了一个《WebBrowser控件的简单应用2》,提到了在NewWindow事件中打开新窗口的例子。有网友“队长 ”提出那个事件得到的参数是本页面的,而不是新页面的,经过测试,果然url参数不是新页面的。
Open新页面要处理的:
1:<<a href=’xxxxx’ target=’_blank’>>;
2: onclick=’window.open’ ;
3:引用js文件 ;
4:ClientScript.RegisterStartupScript();等。
5:还有要实现在打开的页面里能用window.opener对象
Close要处理的:
1:onclick=’window.close ;
2:引用js文件 ;
3:ClientScript.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.open和RegisterStartupScript的,可以通过替换js来实现。
本来的window.open函数,在程序完成加载之后,我把这个函数修改成window.external.open,
然后,我把我的AppBrowser类里面加入几个public的Open函数来对应原来的js的open函数就可以了。
这是一个代码实现。
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效果的浏览器)

这个模型里面,作者自己封装并且扩展了这个控件,是个最终极的解决方法。
主要思路:提供了一个将要打开新窗口的事件,并且提供更多的参数。这些参数来自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
结果非常不错。
主要处理的几个地方:
NewWindow2
和
NewWindow3
:处理新打开窗口
BeforeNavigate2
:获得将要打开的窗口的地址。
主要提供的新事件:_StartNewWindow(object sender, BrowserExtendedNavigatingEventArgs e)
下边这一个是我的第二个AppBrowser类,使用上边封装扩展之后的WebBrower控件。

AppBrowser2 source code
1
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
2
public partial class AppBrowser2 : Form
3
{
4
property#region property
5
private string _url;
6
public string URL
7
{
8
get
{ return _url; }
9
set
{ this._url = value; }
10
}
11
12
private ExtendedWebBrowser _browser;
13
// Allows other code to obtain a reference to the extended web browser component
14
private ExtendedWebBrowser WebBrowser
15
{
16
get
{ return _browser; }
17
}
18
#endregion
19
cons.#region cons.
20
public AppBrowser2()
21
{
22
InitializeComponent();
23
}
24
public AppBrowser2(string url)
25
{
26
InitializeComponent();
27
_browser = new ExtendedWebBrowser();
28
_browser.Dock = DockStyle.Fill;
29
_browser.DownloadComplete += new EventHandler(_browser_DownloadComplete);
30
_browser.Navigated += new WebBrowserNavigatedEventHandler(_browser_Navigated);
31
_browser.StartNewWindow += new EventHandler<BrowserExtendedNavigatingEventArgs>(_browser_StartNewWindow);//get js:window.open or <a href event
32
_browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(_browser_DocumentCompleted);
33
_browser.StatusTextChanged += new EventHandler(_browser_StatusTextChanged);
34
_browser.Quit += new EventHandler(_browser_Quit);//get js:window.close event
35
this.pnl_container.Controls.Add(_browser);
36
this.URL = url;
37
_browser.Navigate(URL);
38
_browser.ObjectForScripting = this;//set this to be the COM handler
39
}
40
#endregion
41
42
window : close and open#region window : close and open
43
void _browser_Quit(object sender, EventArgs e)
44
{
45
this.Close();
46
}
47
48
void _browser_StartNewWindow(object sender, BrowserExtendedNavigatingEventArgs e)
49
{
50
AppBrowser2 ab2 = new AppBrowser2(e.Url.ToString());
51
e.AutomationObject = ab2.WebBrowser.Application;//for 'window.opener'
52
ab2.Show();
53
}
54
#endregion
55
other browser event#region other browser event
56
void Window_Error(object sender, HtmlElementErrorEventArgs e)
57
{
58
// We got a script error, record it
59
//ScriptErrorManager.Instance.RegisterScriptError(e.Url, e.Description, e.LineNumber);
60
// Let the browser know we handled this error.
61
e.Handled = true;
62
}
63
void _browser_DownloadComplete(object sender, EventArgs e)
64
{
65
// Check wheter the document is available (it should be)
66
if (this.WebBrowser.Document != null)
67
{
68
// Subscribe to the Error event
69
this.WebBrowser.Document.Window.Error += new HtmlElementErrorEventHandler(Window_Error);
70
UpdateAddressBox();
71
}
72
}
73
void _browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
74
{
75
UpdateAddressBox();
76
}
77
void _browser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
78
{
79
UpdateAddressBox();
80
}
81
82
void _browser_StatusTextChanged(object sender, EventArgs e)
83
{
84
this.toolStripStatusState.Text = WebBrowser.StatusText;
85
}
86
// Updates the info on the window
87
private void UpdateAddressBox()
88
{
89
this.toolStripStatusTitle.Text = this.WebBrowser.Document.Title;
90
}
91
#endregion
92
93
external function for js#region external function for js
94
/**//// <summary>
95
/// this function can be invoked by js in html
96
/// like this 'javascript:window.external.ShowMessage('this is invoke from web');'
97
/// </summary>
98
/// <param name="msg"></param>
99
public void ShowMessage(string msg)
100
{
101
MessageBox.Show(msg, "alert");
102
}
103
104
/**//// <summary>
105
/// open new, for JS: window.open
106
/// </summary>
107
/// <param name="url"></param>
108
public void Open(string url)
109
{
110
AppBrowser2 newAB2 = new AppBrowser2(url);
111
newAB2.Show();
112
}
113
#endregion
114
}