文章出處

摘自:http://blog.csdn.net/cometnet/article/details/5261192

一般情況下,當ReadyState屬性變成READYSTATE_COMPLETE時,Webbrowser控件會通過觸發DocumentCompleted事件來指示網頁加載完畢。但當加載的網頁包含frame時,可能會多次觸發該事件,所以不能簡單地通過它來判斷網頁加載完畢。

從微軟的官方網站上了解到,并非每個frame都對應了一個DocumentCompleted事件,只有觸發了DownloadBegin事件的frame才會有相應的DocumentCompleted事件。另外,最外層的frame總是最后觸發DocumentCompleted事件。DocumentCompleted事件具有一個IDispatch *類型的參數,它指示了是在哪個frame上觸發的該事件。所以,要判斷文檔是否加載完畢,只需要判斷IDispatch *參數是否是Webbrowser控件的IDispatch。

微軟support網站上關于這個問題的說明:

http://support.microsoft.com/?scid=kb%3Ben-us%3B180366&x=9&y=14

 

原文及譯文如下:(我用Google翻譯的,不一定正確,大家見諒)

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.

在Internet Explorer WebBrowser控件激發DocumentComplete事件完成時下載網頁。您可以在應用程序中創建的這一事件的事件處理函數。本文介紹的步驟可以參與決定,如果WebBrowser控件下載完成一個網頁。

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.

WebBrowser控件激發DocumentComplete事件時,它的readyState屬性更改為READYSTATE_COMPLETE。這表明,WebBrowser控件已完成下載的網頁。以下是一些對這起事件的要點: 在網頁的情況下,沒有框架,一旦被激發的DocumentComplete一切完成之后。 在多個幀的情況,得到的DocumentComplete多次發射。不是每幀觸發這一事件,但每個幀觸發一個DownloadBegin事件觸發相應的DocumentComplete事件。 DocumentComplete事件的IDispatch *有一個參數,它是框架(shdocvw),這些被激發的DocumentComplete的IDispatch。 在頂級框架火災最終的DocumentComplete。因此,要檢查一個頁面完成下載,您需要檢查的IDispatch *參數作為WebBrowser控件的IDispatch相同。

 

For Visual Basic, here is code that performs this check:

  1. Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object,URL As Variant)  
  2.    If (pDisp Is WebBrowser1.Object) Then  
  3.       Debug.Print "Web document is finished downloading"  
  4.    End If  
  5. End Sub  
  6.       

 

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.

為了處理在Visual C + + DocumentComplete事件,并確定如果網頁下載完成后,按照下列步驟。
請注意,您按照步驟取決于你如何使用WebBrowser控件。 如果你在創建一個CWnd / CView對象WebBrowser控件,則必須按照步驟1至4。 如果您要創建一個CDialog在WebBrowser控件/ CFormView對象,只需要按照步驟4。 如果您使用的是CHtmlView類提供與Visual C + + 6.0,重寫CHtmlView::的DocumentComplete()和后續步驟4,使用該CHtmlView類m_pBrowserApp成員訪問WebBrowser控件。

1.Define the OnDocumentComplete method in the header file for your CWnd/CView-derived class:

  1. afx_msg void OnDocumentComplete(LPDISPATCH lpDisp,VARIANT FAR* URL);  

 

2.Declare the event sink in the same header file:

  1. DECLARE_EVENTSINK_MAP()  

 

3.In the implementation file (.cpp) for your CWnd/CView-derived class, implement the event sink map:

  1. BEGIN_EVENTSINK_MAP(CYourView, CView)  
  2.    ON_EVENT(CWBTstView, ID_WEB_BROWSE, 259 /* DocumentComplete */,  
  3.             OnDocumentComplete, VTS_DISPATCH VTS_PVARIANT)  
  4. END_EVENTSINK_MAP()  

 

4.Implement the OnDocumentComplete method:

  1. void CWBTstView::OnDocumentComplete(LPDISPATCH lpDisp,  
  2.                                     VARIANT FAR* URL)  
  3. {  
  4.    IUnknown*  pUnk;  
  5.    LPDISPATCH lpWBDisp;  
  6.    HRESULT    hr;  
  7.   
  8.    pUnk = m_webBrowser.GetControlUnknown();  
  9.    ASSERT(pUnk);  
  10.   
  11.    hr = pUnk->QueryInterface(IID_IDispatch, (void**)&lpWBDisp);  
  12.    ASSERT(SUCCEEDED(hr));  
  13.   
  14.    if (lpDisp == lpWBDisp )  
  15.    {  
  16.       // Top-level Window object, so document has been loaded  
  17.       TRACE("Web document is finished downloading/n");  
  18.    }  
  19.   
  20.   lpWBDisp->Release();  
  21. }  

 

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.
這種方法在WebBrowser控件時,導航到一個網頁,更改頂級框架。說,如果出現導航本身的框架內,那么最后一個DocumentComplete是發射的是,框架,而不是頂級框架。例如,考慮以下情況。
WebBrowser控件主持一個框架。在一個框架集框架,在用戶點擊鏈接打開在框架本身就是一種新的一頁,保持完整的框架休息。新的頁面可能包含多個幀了。因此,將有多個(每個新的框架之一)的DocumentComplete通知。但是,由于頂級框架沒有改變,最后的DocumentComplete將是該改變了框架。
如果您是在為最后文件在這種情況下完成檢查感興趣,你可以做以下操作: 檢查的一個DocumentComplete的IDispatch參數是相同的第一NavigateComplete2事件的IDispatch參數。自第一NavigateComplete2是頂級幀和最后一個DocumentComplete也是頂級框架,做了這樣的方式比較,判斷該頁面進行下載。
 
Here is some sample C++ code:
  1. LPDISPATCH glpDisp = NULL; // global LPDISPATCH, can also  
  2.                            // be of class scope  
  3.   
  4. // NavigateComplete2 event  
  5. void CWebbrDlg::OnNavigateComplete2Explorer1(LPDISPATCH pDisp,  
  6.                                              VARIANT FAR* URL)  
  7. {  
  8.    // Check if glpDisp is NULL. If NULL, that means it is  
  9.    // the top level NavigateComplete2. Save the LPDISPATCH  
  10.    if (!glpDisp)  
  11.       glpDisp = pDisp;  
  12. }  
  13.   
  14. void CWebbrDlg::OnDocumentCompleteExplorer1(LPDISPATCH pDisp,  
  15.                                             VARIANT FAR* URL)  
  16. {  
  17.    if (glpDisp && glpDisp == pDisp)  
  18.    {  
  19.       // if the LPDISPATCH are same, that means  
  20.       // it is the final DocumentComplete. Reset glpDisp  
  21.       TRACE("Document is done downloading");  
  22.       glpDisp = NULL;  
  23.    }  
  24. }  

 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()