seiph80
seiph80

Reputation: 1

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

this is the first time I'm posting a question here; I have searched and searched and searched here and other places and I cannot seem to get any results. I'm using VISUAL BASIC 2015 in Visual Studio 2015. QUESTION: I need to have a modal window/popup from a particular website remain INSIDE the web browser control/window on my form (WebBrowser1); when a particular link is clicked, the modal window/popup jumps out of the form and directly to the user on their screen. I have to keep this popup inside because there are other links to be clicked on that popup, but if it jumps out of the web browser control, no code will work since it's outside WebBrowser1. What I have found is code for older versions, and not 2015; if anything I can even add WebBrowser2 to have the popups/modal windows appear there if possible, just as long as I can code them to keep clicking inside the form. PLEASE HELP! THANK YOU!

Upvotes: 0

Views: 1650

Answers (1)

Sheng Jiang 蒋晟
Sheng Jiang 蒋晟

Reputation: 15271

window.open (and a click on <a target="_blank"> etc) can be handled via the NewWindow2 event. Hans already pointed out how to do that in comments. NewWindow3 works too, but need at least Windows XP SP2.

As for window.showModalDialog, it is a bit tricky. IE has IDispatchEx (wrapped as IExpando in .Net) implemented on scripting objects so you replace the methods and properties with your own implementation. But window.showModalDialog shows a dialog that has arguments and return values, you need to override those properties in the modal dialog you create too. The code looks roughly like 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;
    }
}

and in the Load event handler of MyShowModalDialog you call something like webBrowser1.Navigate to show the page requested by the parent page.

Now you need to pass the arguments to the webbrowser control on the new form. Do the same as above but replace another property this time.

expando.RemoveProperty("dialogArguments");
expando.AddProperty("dialogArguments")
    .SetValue(expando,this.DialogArguments);

This will let the web page access the value passed from MyShowModalDialog and stored in this.DialogArguments.

The earliest you can access the DOM is in webBrowser1_DocumentCompleted. By that time the scipts on the page that read window.dialogArguments are probably already executed and got nothing. After overriding window.dialogArguments, you need to study the script on the page to find out how to revert that. for example, if the page has

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

you need to change the values of sFirstName and sLastName then change the innerText property of the span, probably identify via its relationship with a named div or table cell. You can write the necessary changes in a script and call it via HtmlDocument.InvokeScript.

If the page returns a value to its parent, you need to pass it on to your parent form too. Override window.returnValue so when the script writes to window.returnValue it writes to a variable you provided

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

Upvotes: 0

Related Questions