Web浏览器控件,模态窗口/弹出到STAY INSIDE Web浏览器控件,用于Visual Studio 2015 / Visual Basic 2015

时间:2016-06-06 20:22:57

标签: vb.net visual-studio-2015 webbrowser-control

这是我第一次在这里发帖提问;我在这里和其他地方搜索,搜索和搜索,我似乎无法得到任何结果。我在Visual Studio 2015中使用VISUAL BASIC 2015.问题:我需要在特定网站上保留一个模态窗口/弹出窗口保留在我的窗体上的Web浏览器控件/窗口(WebBrowser1);当单击特定链接时,模态窗口/弹出窗口跳出窗体并直接跳到屏幕上的用户。我必须保留这个弹出窗口,因为在弹出窗口中有其他链接被点击,但是如果它跳出Web浏览器控件,则没有代码可以工作,因为它在WebBrowser1之外。我发现的是旧版本的代码,而不是2015;如果有的话我甚至可以添加WebBrowser2以使弹出窗口/模态窗口出现在那里,只要我可以编码它们以保持在窗体内单击。请帮忙!谢谢!

1 个答案:

答案 0 :(得分:0)

可以通过window.open事件处理

NewWindow2(并点击<a target="_blank">等)。汉斯已经在评论中指出了如何做到这一点。 NewWindow3也可以,但至少需要Windows XP SP2。

至于window.showModalDialog,这有点棘手。 IE在IDispatchEx上实现了IExpando(在{。}中包装为scripting objects),因此您可以使用自己的实现替换方法和属性。但是window.showModalDialog显示了一个包含参数和返回值的对话框,您需要在您创建的模式对话框中覆盖这些属性。代码看起来大致像tis:

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);