代码之家  ›  专栏  ›  技术社区  ›  Proximo

javascript window.opener对象在.NET WebBrowser控件新窗口上为空

  •  4
  • Proximo  · 技术社区  · 15 年前

    我在.NET框架的Webbroswer控件中有一个弹出窗口,我用类似这样的NewWindow事件处理程序捕获它。

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

    新弹出窗口位于新窗体中,其中包含WebBrowser控件的新实例。

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

    我的问题是window.opener对象在进程中为空。

    页面使用该字段将用户返回到原始窗口,并在表单上填充一些值。

    是否仍要将window.opener对象从一个WebBrowser控件传递到下一个?这似乎不可能奏效,但我必须尝试。

    谢谢

    2 回复  |  直到 7 年前
        1
  •  4
  •   talles    8 年前

    是的,有方法传递窗口。将对象从一个WebBrowser控件打开到下一个。
    有关详细信息,请参阅下面的代码。

    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.我明白,这仍然是事实的可能性很小,但是,无论如何=)

        2
  •  1
  •   yogihw    7 年前

    对于那些正在寻找WPF版本的解决方案的用户,请将setopener函数重写为以下内容:

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

    在子侧WebBrowser的事件处理程序中使用它:

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

    以及WPF部分:

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

    希望我能把别人从数小时的试验、错误和无休止的谷歌搜索中拯救出来。