的DocumentComplete是发射前页面完全加载加载、页面、DocumentComplete

2023-09-04 04:25:24 作者:谈笑风生

为什么web浏览器COM对象火的页之前DocumentComplete事件被加载?我想这事件只发射时,页面被完全浏览器的窗口中呈现。

这是我的BHO实现:

  [标记有​​ComVisible特性(真),
GUID(5a954357-44bd-4660-9570-17bb1b71eeaa),
ClassInterface(ClassInterfaceType.None)
公共类BHO:接口IObjectWithSite
{
    私人web浏览器的浏览器;
    私营的DateTime startTime时;
    私人日期时间endTime的;
    私有对象_pUnkSite;

    公共无效OnDocumentComplete(对象pDisp,参考目标URL)
    {
        如果(!的ReferenceEquals(pDisp,_pUnkSite))
        {
            返回;
        }

        使用(StreamWriter的SW = File.AppendText(log_path))
        {
            endTime的= DateTime.Now;
            时间跨度TS = endTime.Subtract(startTime时);
            sw.WriteLine(完成了{0} {1},ts.Seconds,ts.Milliseconds);
        }

    }

    公共无效OnBeforeNavigate2(对象pDisp,参考目标URL,引用对象旗帜,裁判的对象TargetFrameName,引用对象的PostData,引用对象接头,REF布尔取消)
    {
        如果(!的ReferenceEquals(pDisp,_pUnkSite))
        {
            返回;
        }
        的startTime = DateTime.Now;
    }

    公众诠释SetSite(对象的网站)
    {
        如果(网站!= NULL)
        {
            _pUnkSite =网站;
            浏览器=(web浏览器)的网站;
            browser.DocumentComplete + =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
            browser.BeforeNavigate2 + =新DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
        }
        其他
        {
            browser.DocumentComplete  -  =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
            browser.BeforeNavigate2  -  =新DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
            浏览器= NULL;

        }
        返回0;
    }

    公众诠释GetSite(REF的Guid GUID,出来的IntPtr ppvSite)
    {
        IntPtr的朋克= Marshal.GetIUnknownForObject(浏览器);
        INT HR = Marshal.QueryInterface(朋克,裁判GUID,出ppvSite);
        Marshal.Release(朋克);

        返回小时;
    }
}
 

解决方案 Google Chrome浏览器 控制台全解析

由于有一个页面上的其他文件。一个IFRAME,或图像,例如,将触发的DocumentComplete 事件。你需要做的是确保所提出的目标的DocumentComplete 是实际的页面。例如:

 私人无效_webBrowser2Events_DocumentComplete(对象pdisp,参考目标URL)
{
    如果(!的ReferenceEquals(pdisp,_pUnkSite))
    {
        //退出,因为一个DocumentComplete不是文档完整的页面。
        返回;
    }
    //这里做你的正常的东西
}
 

其中, _pUnkSite 是从的 SetSite

Why does DocumentComplete event of WebBrowser COM object fire before page is loaded? I thought that this event is only fired when page is fully rendered in browser's window.

this is my BHO implementation:

[ComVisible(true),
Guid("5a954357-44bd-4660-9570-17bb1b71eeaa"),
ClassInterface(ClassInterfaceType.None)]
public class BHO : IObjectWithSite
{
    private WebBrowser browser;
    private DateTime startTime;
    private DateTime endTime;
    private object _pUnkSite;

    public void OnDocumentComplete(object pDisp, ref object URL)
    {
        if (!ReferenceEquals(pDisp, _pUnkSite))
        {
            return;
        }

        using (StreamWriter sw = File.AppendText("log_path"))
        {
            endTime = DateTime.Now;
            TimeSpan ts = endTime.Subtract(startTime);
            sw.WriteLine("completed in {0}.{1}", ts.Seconds, ts.Milliseconds);
        }

    }

    public void OnBeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
    {
        if (!ReferenceEquals(pDisp, _pUnkSite))
        {
            return;
        }
        startTime = DateTime.Now;
    }

    public int SetSite(object site)
    {
        if (site != null)
        {
            _pUnkSite = site;
            browser = (WebBrowser)site;   
            browser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
            browser.BeforeNavigate2 += new DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
        }
        else
        {
            browser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
            browser.BeforeNavigate2 -= new DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
            browser = null;

        }
        return 0;
    }

    public int GetSite(ref Guid guid, out IntPtr ppvSite)
    {
        IntPtr punk = Marshal.GetIUnknownForObject(browser);
        int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
        Marshal.Release(punk);

        return hr;
    }
}

解决方案

Because there are other documents on a page. An iframe, or an image, for example, will fire the DocumentComplete event. What you need to do is ensure that the object that raised DocumentComplete is the actual page. For example:

private void _webBrowser2Events_DocumentComplete(object pdisp, ref object url)
{
    if (!ReferenceEquals(pdisp, _pUnkSite))
    {
        //Exit, because the DocumentComplete is not the document complete for the page.
        return;
    }
    //Do your normal stuff here
}

Where _pUnkSite is the site that was passed in from SetSite.