window.open(以及点击<a target="_blank"> 等)可以通过NewWindow2 事件进行处理。 Hans 已经指出如何在 cmets 中做到这一点。 NewWindow3 也可以,但至少需要 Windows XP SP2。
至于window.showModalDialog,有点棘手。 IE 在scripting objects 上实现了IDispatchEx(在.Net 中包装为IExpando),因此您可以用自己的实现替换方法和属性。但是 window.showModalDialog 显示了一个具有参数和返回值的对话框,您也需要在您创建的模态对话框中覆盖这些属性。代码大致如下:
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//skip events from frames
if(WebBrowserReadyState.Complete!=webBrowser1.ReadyState) return;
if(FindLoginFormOnPage()) {DoLogin();return;}
if(IsWelcomePage()){NavigateToPage1();return;}
if(IsPage1()){SubmitFormOnPage1();return;}
if(IsPage1FormResult()){
var document=webBrowser1.Document.DomDocument as mshtml.ITMLDocument2;
var expando =(IExpando)document.parentWindow;
expando.RemoveMember(expando.GetMethod("showModalDialog"
,BindingFlags.Instance | BindingFlags.Public);
expando.AddMethod("showModalDialog"
,new ShowModalDialogDelegate(this.MyShowModalDialog));
}
......
}
object MyShowModalDialog(string url, object varArgIn, object options)
{
using(FromMyShowModalDialog myShowModalDialog
=new MyShowModalDialog())
{
myShowModalDialog.StartupUrl=url;
myShowModalDialog.DialogArguments=varArgIn;
//omit the code to parse options
//and set dialog height/width/topleft location etc
if(myShowModalDialog.ShowDialog()==DialogResult.OK)
{
//do something on the return value before passing to the scripts
......
return myShowModalDialog.ReturnValue;
}
return null;
}
}
在 MyShowModalDialog 的 Load 事件处理程序中,您调用类似 webBrowser1.Navigate 的内容来显示父页面请求的页面。
现在您需要将参数传递给新表单上的 webbrowser 控件。执行与上述相同的操作,但这次替换另一个属性。
expando.RemoveProperty("dialogArguments");
expando.AddProperty("dialogArguments")
.SetValue(expando,this.DialogArguments);
这将使网页访问从 MyShowModalDialog 传递并存储在 this.DialogArguments 中的值。
最早可以访问 DOM 的是 webBrowser1_DocumentCompleted。到那时,页面上读取 window.dialogArguments 的 scipts 可能已经执行并且什么也没有得到。覆盖 window.dialogArguments 后,您需要研究页面上的脚本以了解如何恢复该脚本。例如,如果页面有
<head>
<script>
var oMyObject = window.dialogArguments;
var sFirstName = oMyObject.firstName;
var sLastName = oMyObject.lastName;
</script>
...
<span style="color: 00ff7f">
<script>
document.write(sFirstName);
</script>
</span>
您需要更改 sFirstName 和 sLastName 的值,然后更改 span 的 innerText 属性,可能通过其与命名 div 或表格单元格的关系来识别。您可以在脚本中编写必要的更改并通过 HtmlDocument.InvokeScript 调用它。
如果页面向其父级返回一个值,您也需要将其传递给您的父级表单。覆盖 window.returnValue 以便当脚本写入 window.returnValue 时,它会写入您提供的变量
......
expando.RemoveProperty("returnValue");
expando.AddProperty("returnValue").SetValue(expando,this.ReturnValue);