繁体   English   中英

Web浏览器控件,用于Visual Studio 2015 / Visual Basic 2015的STAINS INSIDE Web浏览器控件的模式窗口/弹出窗口

[英]Web browser control, modal window/popup to STAY INSIDE web browser control for Visual Studio 2015/Visual Basic 2015

这是我第一次在这里发布问题; 我已经在这里和其他地方进行了搜索,似乎无法获得任何结果。 我在Visual Studio 2015中使用VISUAL BASIC2015。问题:我需要让特定网站上的模式窗口/弹出窗口保留在表单(WebBrowser1)上的Web浏览器控件/窗口内。 当单击特定链接时,模式窗口/弹出窗口会跳出表单,并直接在屏幕上跳转到用户。 我必须将这个弹出窗口保留在里面,因为在该弹出窗口上还需要单击其他链接,但是如果它跳出Web浏览器控件,则由于它不在WebBrowser1之外,因此没有任何代码可以工作。 我发现的是旧版本的代码,而不是2015年的代码; 如果可以的话,我什至可以添加WebBrowser2以使弹出窗口/模式窗口出现在其中,只要我可以对它们进行编码以保持在表单内部单击即可。 请帮忙! 谢谢!

window.open (和<a target="_blank">等的单击)可以通过NewWindow2事件处理。 汉斯已经在评论中指出了如何做到这一点。 NewWindow3也可以使用,但至少需要Windows XP SP2。

至于window.showModalDialog ,这有点棘手。 IE在脚本对象上实现了IDispatchEx (在.Net中包装为IExpando ),因此您可以用自己的实现替换方法和属性。 但是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的页面上的脚本可能已经执行,却一无所获。 覆盖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的值,然后更改范围的innerText属性,可能通过其与命名div或表单元格的关系进行标识。 您可以在脚本中编写必要的更改,然后通过HtmlDocument.InvokeScript进行调用。

如果页面向其父级返回一个值,那么您也需要将其传递给父级表单。 覆盖window.returnValue,因此当脚本写入window.returnValue时,它将写入您提供的变量

 ......
expando.RemoveProperty("returnValue");
expando.AddProperty("returnValue").SetValue(expando,this.ReturnValue);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM