How To Determine When a Page Is Done Loading in WebBrowser Control
2016-10-12 21:20
549 查看
https://support.microsoft.com/en-us/kb/180366
In the case of a page with no frames, DocumentComplete is fired once after everything is done.
In case of multiple frames, DocumentComplete gets fired multiple times. Not every frame fires this event, but each frame that fires a DownloadBegin event fires a corresponding DocumentComplete event.
The DocumentComplete event has a IDispatch* parameter, which is the IDispatch of the frame (shdocvw) for which DocumentComplete is fired.
The top-level frame fires the DocumentComplete in the end. So, to check if a page is done downloading, you need to check if the IDispatch* parameter is same as the IDispatch of the WebBrowser control.
For Visual Basic, here is code that performs this check:
To handle the DocumentComplete event in Visual C++ and determine if the download of the Web page is complete, follow these steps.
Note that the steps you follow depend on the way you use the WebBrowser control.
If you are creating the WebBrowser control in a CWnd/CView object, you must follow steps 1 to 4.
If you are creating the WebBrowser control in a CDialog/CFormView object, only need to follow step 4.
If you are using the CHtmlView class provided with Visual C++ 6.0, override CHtmlView::DocumentComplete() and follow step 4, using the m_pBrowserApp member of the CHtmlView class to access the WebBrowser control.
Define the OnDocumentComplete method in the header file for your CWnd/CView-derived class:
Declare the event sink in the same header file:
In the implementation file (.cpp) for your CWnd/CView-derived class, implement the event sink map:
Implement the OnDocumentComplete method:
This approach works when the WebBrowser control navigates to a page that changes the top-level frame. Say if the navigation occurs within a frame itself, then the final DocumentComplete that is fired is that of the frame and not the top-level frame. For example, consider the following scenario.
The WebBrowser control is hosting a frameset. Within one frame of the frameset, the user clicks on a link that opens a new page in the frame itself and keeps the rest of the frameset intact. The new page could contain multiple frames again. So, there will be multiple DocumentComplete notifications (one for each new frame). But, since the top-level frame has not changed, the final DocumentComplete would be that of the frame that has changed.
If you are interested in checking for the final document complete in this scenario, you could do the following:
Check if the IDispatch parameter of the DocumentComplete is the same as the IDispatch parameter of first NavigateComplete2 event. Since the first NavigateComplete2 is of the top-level frame and the last DocumentComplete is also of the top-level frame, doing a comparison in such a fashion will tell whether the page is done downloading.
Here is some sample C++ code:
Keywords:
kbhowto KB180366
Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered “as is” and will no longer be updated.Summary
The Internet Explorer WebBrowser control fires the DocumentComplete event when it is finished downloading a Web page. You can create a event handler function in your application for this event. This article describes the steps to take in determining if a the WebBrowser control is finished downloading a Web page.More information
The WebBrowser control fires the DocumentComplete event when its ReadyState property is changed to READYSTATE_COMPLETE. This indicates that the WebBrowser control has completed downloading the Web page. Here are some important points regarding this event:In the case of a page with no frames, DocumentComplete is fired once after everything is done.
In case of multiple frames, DocumentComplete gets fired multiple times. Not every frame fires this event, but each frame that fires a DownloadBegin event fires a corresponding DocumentComplete event.
The DocumentComplete event has a IDispatch* parameter, which is the IDispatch of the frame (shdocvw) for which DocumentComplete is fired.
The top-level frame fires the DocumentComplete in the end. So, to check if a page is done downloading, you need to check if the IDispatch* parameter is same as the IDispatch of the WebBrowser control.
For Visual Basic, here is code that performs this check:
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
To handle the DocumentComplete event in Visual C++ and determine if the download of the Web page is complete, follow these steps.
Note that the steps you follow depend on the way you use the WebBrowser control.
If you are creating the WebBrowser control in a CWnd/CView object, you must follow steps 1 to 4.
If you are creating the WebBrowser control in a CDialog/CFormView object, only need to follow step 4.
If you are using the CHtmlView class provided with Visual C++ 6.0, override CHtmlView::DocumentComplete() and follow step 4, using the m_pBrowserApp member of the CHtmlView class to access the WebBrowser control.
Define the OnDocumentComplete method in the header file for your CWnd/CView-derived class:
afx_msg void OnDocumentComplete(LPDISPATCH lpDisp, VARIANT FAR* URL);
Declare the event sink in the same header file:
DECLARE_EVENTSINK_MAP()
In the implementation file (.cpp) for your CWnd/CView-derived class, implement the event sink map:
BEGIN_EVENTSINK_MAP(CYourView, CView) ON_EVENT(CWBTstView, ID_WEB_BROWSE, 259 /* DocumentComplete */, OnDocumentComplete, VTS_DISPATCH VTS_PVARIANT) END_EVENTSINK_MAP()
Implement the OnDocumentComplete method:
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(); }
This approach works when the WebBrowser control navigates to a page that changes the top-level frame. Say if the navigation occurs within a frame itself, then the final DocumentComplete that is fired is that of the frame and not the top-level frame. For example, consider the following scenario.
The WebBrowser control is hosting a frameset. Within one frame of the frameset, the user clicks on a link that opens a new page in the frame itself and keeps the rest of the frameset intact. The new page could contain multiple frames again. So, there will be multiple DocumentComplete notifications (one for each new frame). But, since the top-level frame has not changed, the final DocumentComplete would be that of the frame that has changed.
If you are interested in checking for the final document complete in this scenario, you could do the following:
Check if the IDispatch parameter of the DocumentComplete is the same as the IDispatch parameter of first NavigateComplete2 event. Since the first NavigateComplete2 is of the top-level frame and the last DocumentComplete is also of the top-level frame, doing a comparison in such a fashion will tell whether the page is done downloading.
Here is some sample C++ code:
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; } }
Properties
Article ID: 180366 - Last Review: 06/22/2014 18:46:00 - Revision: 4.0Keywords:
kbhowto KB180366
相关文章推荐
- (C#) A demo on how to auto fill out the "account" value in log in web page in "WebBrowser" control.
- How to Determine if a file is a .Net assembly (in Delphi and C#)
- How to grant access to SQL logins on a standby database when the guest user is disabled in SQL Serve
- How to duplicate a controlfile when ASM is involved
- How to programmatically assign a SkinID to a control while using a master page in ASP.net 2.0
- How to get IOleSite interface of the WebBrowser in an ActiveX control
- How to call page method in UserControl?
- How to determine who is logged on to a database by using Microsoft Jet UserRoster in Access 2000
- Know How And When To Use System.Message_Level To Control Messages In Oracle Forms
- How to get a type in C++ when its template argument is the argument
- How to run a user control assembly that is hosted on Internet Information Services (IIS) in Internet Explorer
- Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive
- How to reclaim space in InnoDB when innodb_file_per_table is ON
- How to programmatically assign a SkinID to a control while using a master page in ASP.net 2.0
- how to know wether an element is exist in a html page.
- [quote] How to determine what target is given in Makefile from the make command-line?
- how to tag a photo to be used as a thumbnail when page is linked to on facebook
- vs2005下出现“Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive”的解决方法
- How to get the DOM of a WebBrowser control from a window handle (VB6)
- how to display different title in one master page