c#,WebBrowser 判断网页是否加载完毕

private  void button1_Click(object sender, EventArgs e)

        {

            wb.Url = new Uri("http://www.baidu.com");

            wb.DocumentCompleted+=new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);

//这是给wb添加载入完毕的事件

        }

        private  void wb_DocumentCompleted(object sender, EventArgs e)//这个就是当网页载入完毕后要进行的操作

        {

            richTextBox1.Text = wb.DocumentText;//输出载入网页的HTML代码到文本框

        }

一般情况下,当ReadyState属性变成READYSTATE_COMPLETE时,Webbrowser控件会通过触发DocumentCompleted事件来指示网页加载完毕。但当加载的网页包含frame时,可能会多次触发该事件,所以不能简单地通过它来判断网页加载完毕。

从微软的官方网站上了解到,并非每个frame都对应了一个DocumentCompleted事件,只有触发了DownloadBegin事件的frame才会有相应的DocumentCompleted事件。另外,最外层的frame总是最后触发DocumentCompleted事件。DocumentCompleted事件具有一个IDispatch *类型的参数,它指示了是在哪个frame上触发的该事件。所以,要判断文档是否加载完毕,只需要判断IDispatch *参数是否是Webbrowser控件的IDispatch.

-----------------------下文摘自msdn----------------------------------

WebBrowser 控件触发 DocumentComplete 事件的 ReadyState 属性更改为 READYSTATE_COMPLETE 时。 这表示 WebBrowser 控件已完成下载网页。 以下是有关此事件的一些要点:
在带有没有框架页的情况下 DocumentComplete 触发一次所有完成后。
在多个的帧的情况下 DocumentComplete 获取触发多次。 并非每个框架将触发此事件,但触发 DownloadBegin 事件的每个框架将触发相应的 DocumentComplete 事件。
DocumentComplete 事件有一个 IDispatch * 为参数是用于触发 DocumentComplete 框架 (Shdocvw) 的 IDispatch。
顶级框架触发最后 DocumentComplete。 以检查是否不进行页面下载,需要检查 IDispatch * 参数是否与 WebBrowser 控件的 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

要处理 DocumentComplete 事件在 Visual C++ 中的,并确定网页的下载是否完成,请执行这些步骤。

请注意您执行的步骤取决于使用 WebBrowser 控件的方式。
如果要创建 WebBrowser 控件 CWnd / CView 对象中,您必须执行步骤 1 至 4。
如果您 CDialog / CFormView 对象中创建 WebBrowser 控件,只需要执行步骤 4。
如果您使用随 Visual C++6.0 提供 CHtmlView 类,覆盖 CHtmlView::DocumentComplete(),并按照步骤 4,使用 CHtmlView 类的该 m_pBrowserApp 成员访问 WebBrowser 控件。
在头文件为 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();
}

WebBrowser 控件定位到更改顶级框架的页面时,此方法适用。 假设是否在导航发生本身,范围内则触发的最终 DocumentComplete 的图文框与不顶层框架。 是例如请考虑如下情形。

WebBrowser 控件承载一个框架集。 框架集的一个框架中, 用户单击一个链接将外框本身中打开一个新的页面,并使该框架集的其余部分保持不变。 新建页可能再次包含多个框架。 因此,会有多个 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;
   }
}

-------------------------------------------------------------------------------------------

  还有一个方法如下:

用Webbrowser控件加载网页时,通常会用DocumentCompleted事件来指示网页加载完毕。但当加载的网页包含frame时,可能会多次触发该事件,所以不能简单地通过它来判断网页加载完毕。要通过WebBrowserNavigatedEventArgs来判断。

p rivate void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (e.Url != webBrowser1.Document.Url) return;
 
    // 当 e.Url == webBrowser1.Document.Url 我们要的网页加载完毕
    // 加载完毕
    // ...
}

posted @ 2010-02-15 07:50  猪悟能  阅读(10200)  评论(2编辑  收藏  举报