为什么首先为顶级框架触发Webbrowser控件DocumentComplete事件?

时间:2013-09-29 16:11:43

标签: webbrowser-control frames mshtml

基于MSDN上的这篇文章:How To Determine When a Page Is Done Loading in WebBrowser Control,以及过去对StackOverflow的讨论,我认为如果文档有多个框架,DocumentComplete事件会多次触发,最后一次会是对于顶级框架。

但是,使用上面提到的MSDN链接中的确切示例代码,我发现如果在执行导航到URL时有多个DocumentComplete事件,则第一次在下面的代码中满足条件,而不是最后一个时间正如文章似乎表明的那样。后续调用DocumentComplete似乎是针对较低级别的帧,因为条件失败。

IUnknown*  pUnk;
LPDISPATCH lpWBDisp;
HRESULT    hr;
pUnk = m_webBrowser.GetControlUnknown();
ASSERT(pUnk);
hr = pUnk->QueryInterface(IID_IDispatch, (void**)&lpWBDisp);
ASSERT(SUCCEEDED(hr));
if (lpDisp == lpWBDisp )
{
   // Top-level Window object, so document has been loaded
   TRACE("Web document is finished downloading\n");
}
lpWBDisp->Release();

我不确定为什么我观察到的行为与文档中的行为正好相反。关于这一点的任何指示将不胜感激。

背景:我在基于对话框的VC ++ / MFC应用程序中使用此代码,而在DocumentComplete事件中,我希望在文档完全加载时获得某些统计信息。所以我试图使用上面的代码来检测DocumentComplete触发的特定实例是否在页面完全加载时。

2 个答案:

答案 0 :(得分:4)

IMO是在网页完全加载时获得通知的最可靠方式,是附加到window对象的window.onload DOM事件IWebBrowser2::get_Document IHTMLDocument2::get_parentWindow,{{1} }),第一次为特定导航触发DocumentComplete时。然后,当加载所有内部框架时,将触发顶部网页的onload事件。 This answer说明了如何在C#中完成它,而this answer可能有助于在C ++中完成它。

答案 1 :(得分:0)

MSDN doc似乎对我来说:最后一个DISPID_DOCUMENTCOMPLETE是为主框架触发的。{/ p>

我无法为http://www.microsoft.com/重现您的问题,因为该链接为我提供了最终http://www.microsoft.com/fr-fr/default.aspx 单帧

我不喜欢示例代码测试主浏览器的方式(2个IDispatch指针相等)。我这样做是:

  1. QueryInterface IDispatch的{​​{1}}
  2. 进行真正的COM相等测试,即“比较IWebBrowser2中的IUnknown”(我使用IWebBrower2模板中的IsEqualObject方法。