原文:http://support.microsoft.com/kb/180366/zh-cn
web 浏览器控件将触发 DocumentComplete 事件时其 ReadyState 属性更改为 READYSTATE_COMPLETE。这表明 web 浏览器控件已完成下载 Web 页。下面是一些关于此活动的要点:
- 在没有框架的网页的情况下 DocumentComplete 触发一次完成所有内容之后。
- 在多个的框架的情况下 DocumentComplete 获取激发多次。 不是每个框架时触发此事件,但每个框架,将触发 DownloadBegin 事件触发相应 DocumentComplete 事件。
- DocumentComplete 事件有一个 IDispatch * 参数,它是的框架 (shdocvw) 为其触发 DocumentComplete 的 IDispatch。
- 顶层的框架将触发最后 DocumentComplete。可以检查是否进行页下载,您需要检查 IDispatch * 参数是否是相同的 web 浏览器控件 IDispatch。
对于 Visual Basic 此处是执行此检查的代码:Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) If (pDisp Is WebBrowser1.Object) Then Debug.Print "Web document is finished downloading" End If End Sub
请注意您执行该步骤取决于您使用 web 浏览器控件的方法。
- 如果要在 web 浏览器控件中创建一个 cwnd/cview 对象,则必须按照步骤 1 到 4。
- 如果要在 web 浏览器控件中创建一个 cdialog/cformview 对象,只需遵循步骤 4。
- 如果使用的与 Visual c + + 6.0 一起提供的 CHtmlView 类重写 CHtmlView::DocumentComplete(),并按照步骤 4,使用 CHtmlView 类 m_pBrowserApp 成员访问 web 浏览器控件。
- cwnd/cview 派生类的头文件中定义 OnDocumentComplete 方法:
afx_msg void OnDocumentComplete(LPDISPATCH lpDisp, VARIANT FAR* URL);
- 声明事件接收器在相同的头文件中:
DECLARE_EVENTSINK_MAP()
- 在 cwnd/cview 派生类的一个实现文件 (.cpp),实现事件接收映射:
BEGIN_EVENTSINK_MAP(CYourView, CView) ON_EVENT(CWBTstView, ID_WEB_BROWSE, 259 /* DocumentComplete */, OnDocumentComplete, VTS_DISPATCH VTS_PVARIANT) END_EVENTSINK_MAP()
- 实现 OnDocumentComplete 方法:
void CWBTstView::OnDocumentComplete(LPDISPATCH lpDisp, VARIANT FAR* URL) { 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(); }
web 浏览器控件宿主框架集。框架集的一个框架中, 在用户单击一个链接,会在其自身的框架中打开一个新页,并保持框架集的其余部分保持不变。再次在新页可能包含多个帧。因此,将有多个 DocumentComplete 通知 (一个用于每个新的框架)。但一直没有更改顶级框架,因为最终 DocumentComplete 就是框架的已更改。
如果您感兴趣检查在这种情况下完成最终文档您可以执行下列操作:
请检查该 DocumentComplete IDispatch 参数是否 IDispatch 参数的第一个 NavigateComplete2 事件相同。由于第一个 NavigateComplete2 是顶层的框架的并且最后一个 DocumentComplete 也是顶层的框架的进行比较以这样的方式将告诉页是否完成下载。
下面是一些示例 c + + 代码:
LPDISPATCH glpDisp = NULL; // global LPDISPATCH, can also // be of class scope // NavigateComplete2 event void CWebbrDlg::OnNavigateComplete2Explorer1(LPDISPATCH pDisp, VARIANT FAR* URL) { // Check if glpDisp is NULL. If NULL, that means it is // the top level NavigateComplete2. Save the LPDISPATCH if (!glpDisp) glpDisp = pDisp; } void CWebbrDlg::OnDocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT FAR* URL) { if (glpDisp && glpDisp == pDisp) { // if the LPDISPATCH are same, that means // it is the final DocumentComplete. Reset glpDisp TRACE("Document is done downloading"); glpDisp = NULL; } }