一般情况下MS提供的解决方案就能确定了,但有的还是不能,哪位兄弟有更好的办法请告知;
MS的解决方案:http://support.microsoft.com/kb/180366/zh-cn
Internet Explorer web 浏览器控件将触发 DocumentComplete 事件完成后下载 Web 页。此事件的应用程序中,您可以创建事件处理程序函数。本文介绍了在确定是否应采取的步骤完成后 web 浏览器控件下载 Web 页。
Web 浏览器控件激发 DocumentComplete 事件时其 ReadyState 属性更改为 READYSTATE_COMPLETE。这表明 web 浏览器控件已经完成下载 Web 页。以下是有关此事件的一些要点:
- 对于包含无框架的网页,一切都完成后一次激发 DocumentComplete。
- 如果出现多个帧,DocumentComplete 获取激发多次。不是每个框架激发此事件,但每个框架,将触发 DownloadBegin 事件将触发对应的 DocumentComplete 事件。
- DocumentComplete 事件有 IDispatch * 参数,即为其触发 DocumentComplete 框架 (shdocvw) 的 IDispatch。
-
顶级框架,将激发最后 DocumentComplete。这样,请检查页面是下载,您需要检查是否相同的 web 浏览器控件 IDispatch 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
若要处理 Visual C++ 在 DocumentComplete 事件并确定是否 Web 页的下载已完成,请按照下列步骤。
请注意所遵循的步骤取决于您使用 web 浏览器控件的方式。
- 如果您正在 CWnd/CView 对象中创建 web 浏览器控件,则必须按照步骤 1 到 4。
- 如果您正在创建 CDialog/CFormView 对象中的 web 浏览器控件,只需执行第 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()
-
在实现文件 (.cpp) CWnd/CView 派生类中,实现事件接收映射:
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 的框架,并不是顶级框架说。例如,请考虑下面的方案。
Web 浏览器控件所在的框架集。在框架集的某个框架,用户在单击链接本身的框架中打开新页面,并使该框架集的其余部分保持不变。再次,新的页面可能包含多个帧。因此,将有多个 DocumentComplete 通知 (一个用于每个新帧)。但是,尚未更改顶级框架,因为最终
DocumentComplete 的帧的已更改。
如果您有兴趣检查最终的文档完成在此方案中,可以执行以下操作:
检查 DocumentComplete 的 IDispatch 参数是否与第一个 NavigateComplete2 事件的 IDispatch 参数相同。由于第一个 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; } }