Frage

Nun, ich habe eine Pop-up in der WebBroswer Kontrolle des .NET Framework, die mich mit den NewWindow Event-Handler erfassen, wie so.

WebBrowser w = new WebBrowser();
SHDocVw.WebBrowser_V1 web = (SHDocVw.WebBrowser_V1)w.ActiveXInstance;
web.NewWindow += new SHDocVw.DWebBrowserEvents_NewWindowEventHandler(web_NewWindow);

Das neue Popup ist in einer neuen Form mit einer neuen Instanz des WebBrowser-Steuerelement.

void web_NewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed)
    {
        Processed = true;
        WebBrowser w2 = new WebBrowser();

        Form PopUp = new Form();
        PopUp.Controls.Clear();
        PopUp.Controls.Add(w2);
        w2.Dock = DockStyle.Fill;
        PopUp.Show();
        w2.Navigate(URL);
        w2.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(w2_DocumentCompleted);
    }

Mein Problem ist, dass das window.opener Objekt in dem Prozess null ist.

Die Seite verwendet das Feld die Benutzer zurück zum ursprünglichen Fenster zurückzukehren und füllt einige Werte in dem Formular.

Gibt es trotzdem das window.opener Objekt von einem WebBrowser-Steuerelement zum nächsten zu übergeben? Es scheint unmöglich, dass dies funktionieren wird, aber ich muss es versuchen.

Danke

War es hilfreich?

Lösung

Ja, es gibt Möglichkeit, das window.opener Objekt von einem WebBrowser-Steuerelement zum nächsten zu übergeben.
Siehe Code unten.

public class WebBrowserTest
{
    private WebBrowser _wParent;

    // entry point
    public void Navigate(string url)
    {
        _wParent = new WebBrowser();
        SHDocVw.WebBrowser_V1 v1 = (SHDocVw.WebBrowser_V1)w.ActiveXInstance;
        v1.NewWindow += v1_NewWindow;
    }

    private void v1_NewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed)
    {
        // tell, that we'll open new page by ourselves
        Processed = true;

        // open page by ourselves
        WebBrowser w2 = new WebBrowser();
        w2.Navigate(url);

        // wait for document will be loaded to do some magic stuff then
        w2.DocumentCompleted += w2_DocumentCompleted;
    }

    // sets opener for popup window
    // after document in popup window was loaded
    private void w2_DocumentCompleted(object sender, EventArgs e)
    {
        WebBrowser popup = (WebBrowser)sender;
        SetOpener(_wparent, popup);
    }

    // My most favorite method :)
    // Contains exactly that hack, we're talking about
    private void SetOpener(WebBrowser opener, WebBrowser popup)
    {    
        HtmlWindow htmlPopup = popup.Document.Window;
        HtmlWindow htmlOpener = opener.Document.Window;

        // let the dark magic begin

        // actually, WebBrowser control is .NET wrapper around IE COM interfaces
        // we can get a bit closer to them access by getting reference to 
        // "mshtml.IHTMLWindow2" field via Reflection
        FieldInfo fi = htmlPopup.GetType().GetField("htmlWindow2", BindingFlags.Instance | BindingFlags.NonPublic);

        mshtml.IHTMLWindow2 htmlPopup2 = (mshtml.IHTMLWindow2)fi.GetValue(htmlPopup);
        mshtml.IHTMLWindow2 htmlOpener2 = (mshtml.IHTMLWindow2)fi.GetValue(htmlOpener);

        // opener is set here
        htmlPopup2.window.opener = htmlOpener2.window.self;
    }
}

P. S. Ich verstehe, stehen die Chancen, dass es immer noch aktuell ist, sind sehr klein, aber trotzdem =)

Andere Tipps

Für diejenigen, die für WPF-Version der Lösung suchen, schreiben die SetOpener Funktion unter:

public static void SetOpener(System.Windows.Controls.WebBrowser opener, System.Windows.Controls.WebBrowser popup)
{
    mshtml.IHTMLWindow2 htmlPopup = (popup.Document as mshtml.HTMLDocument).parentWindow;
    mshtml.IHTMLWindow2 htmlOpener = (opener.Document as mshtml.HTMLDocument).parentWindow;
    htmlPopup.window.opener = htmlOpener.window.self;
}

Verwenden Sie es in Event-Handler auf das Kind Seite WebBrowser:

private void browser_LoadCompleted(object sender, NavigationEventArgs eventArgs)
        {
            WebBrowser popup = (WebBrowser)sender;
            SetOpener(parentWebBrowser, popup);
        }

Und der WPF Teil:

<Grid>
    <WebBrowser Name="webBrowser" LoadCompleted="browser_LoadCompleted" />
</Grid>

Hoffe, dass ich gerettet nur jemand anderes von Stunden von Versuch, Irrtum und endlosen googeln.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top