HOWTO: Determine When a Page Is Done Loading in WebBrowser Control
ID: Q180366
|
The information in this article applies to:
-
Microsoft Internet Explorer (Programming) versions 5.0, 4.0, 4.01
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:
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();
pUnk->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;
}
}
REFERENCES
Internet Client SDK Help (http://msdn.microsoft.com/redirs/inetsdkredir.asp),
search on: "Reusing the WebBrowser Control" in the "Internet Tools and
Technologies" section.
Additional query words:
DocumentComplete
Keywords : kbIE400 kbIE401 kbIE500 AXSDKWebBrowser
Version : WINDOWS:4.0,4.01,5.0
Platform : WINDOWS
Issue type : kbhowto
|