【问题标题】:Why is the Webbrowser control DocumentComplete event fired for top level frame first?为什么首先为顶级框架触发 Webbrowser 控件 DocumentComplete 事件?
【发布时间】:2013-10-05 11:45:50
【问题描述】:

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

但是,使用上述 MSDN 链接中的确切示例代码,我发现如果在执行 Navigate to a 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 触发的特定实例是在页面完全加载时。

【问题讨论】:

  • 注意:我正在调试与 microsoft.com 等 URL 对应的网页的初始加载,没有考虑进一步的用户操作,例如单击页面上的链接。多个 DocumentComplete 事件都对应于初始页面加载(我相信页面的每一帧都有一个)

标签: webbrowser-control frames mshtml


【解决方案1】:

IMO,当页面完全加载时获得通知的最可靠方法是附加到顶部 window 对象(IWebBrowser2::get_DocumentIHTMLDocument2::get_parentWindow)的 window.onload DOM 事件,当 DocumentComplete 是首次针对特定导航触发。然后,当所有内部框架都加载完毕后,顶部网页的onload 事件将被触发。 This answer 说明了如何在 C# 中完成它,this answer 可能有助于在 C++ 中完成它。

【讨论】:

    【解决方案2】:

    MSDN 文档对我来说似乎是正确的:最后一个 DISPID_DOCUMENTCOMPLETE 是为主框架触发的。

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

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

    1. QueryInterfaceIDispatchIWebBrowser2
    2. 进行真正的 COM 相等性测试,即“比较 IUnknown”中的 2 个 IWebBrower2(我使用 CComPtr 模板中的 IsEqualObject 方法进行此操作。

    【讨论】:

      猜你喜欢
      • 2014-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      相关资源
      最近更新 更多