Webbrowser控件判断网页加载完毕的简单方法 (转)
摘自: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:
- 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
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.
为了处理在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:
- afx_msg void OnDocumentComplete(LPDISPATCH lpDisp,VARIANT FAR* URL);
afx_msg void OnDocumentComplete(LPDISPATCH lpDisp,VARIANT FAR* URL);
2.Declare the event sink in the same header file:
- DECLARE_EVENTSINK_MAP()
DECLARE_EVENTSINK_MAP()
3.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()
BEGIN_EVENTSINK_MAP(CYourView, CView)
ON_EVENT(CWBTstView, ID_WEB_BROWSE, 259 /* DocumentComplete */,
OnDocumentComplete, VTS_DISPATCH VTS_PVARIANT)
END_EVENTSINK_MAP()
4.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();
- }
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:
WebBrowser控件主持一个框架。在一个框架集框架,在用户点击链接打开在框架本身就是一种新的一页,保持完整的框架休息。新的页面可能包含多个帧了。因此,将有多个(每个新的框架之一)的DocumentComplete通知。但是,由于顶级框架没有改变,最后的DocumentComplete将是该改变了框架。
如果您是在为最后文件在这种情况下完成检查感兴趣,你可以做以下操作: 检查的一个DocumentComplete的IDispatch参数是相同的第一NavigateComplete2事件的IDispatch参数。自第一NavigateComplete2是顶级帧和最后一个DocumentComplete也是顶级框架,做了这样的方式比较,判断该页面进行下载。
- 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;
- }
- }
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控件判断网页加载完毕的简单方法 (转)的更多相关文章
- Webbrowser控件判断网页加载完毕的简单方法
一般情况下,当ReadyState属性变成READYSTATE_COMPLETE时,Webbrowser控件会通过触发DocumentCompleted事件来指示网页加载完毕.但当加载的网页包含fra ...
- delphi WebBrowser控件上网页验证码图片识别教程(一)
步骤一:获取网页中验证码图片的url地址 在delphi中加入一个BitBtn和一个memo以及WebBrowser控件实现网页中验证码图片的url地址的获取 程序如下:procedure TForm ...
- jQuery EasyUI动态添加控件或者ajax加载页面后不能自动渲染问题的解决方法
博客分类: jquery-easyui jQueryAjax框架HTML 现象: AJAX返回的html无法做到自动渲染为EasyUI的样式.比如:class="easyui-layout ...
- Winform DevExpress控件库(二) 使用SplashScreenManager控件定制程序加载页面
SplashScreenManager控件:主要作用是显示在进行耗时操作时的等待界面: 位于 工具箱 -> Navigation & Layout(导航栏与布局类控件) 目录下: 在工具 ...
- JS判断页面加载完毕
//JS判断页面加载完毕,再隐藏加载效果层,一个简单的JS加载效果. document.onreadystatechange = function () { if (document.readySta ...
- 使用SplashScreenManager控件定制程序加载页面
需要devexpress版本在12.0及以上才支持 https://www.cnblogs.com/wuhuacong/p/6112461.html 在DevExpress程序中使用SplashScr ...
- Duilib中Webbrowser事件完善使其支持判断页面加载完毕
在多iframe的页面中,需要结合DISPID_DOCUMENTCOMPLETE和DISPID_NAVIGATECOMPLETE2两个事件判断页面是否加载完毕,而duilib中没有提供对DISPID_ ...
- js判断页面加载完毕方法
判断页面加载完成这个方法是很常见的,下面有三个常用的方法,各有利弊. 一.纯js方法 // (1).页面所有内容加载完成执行 window.onload = function(){ } // (2). ...
- 扩展easyUI tab控件,添加加载遮罩效果
项目里要用HighChart显示图表,如果返回的数量量太多,生成图表是一个很耗时的过程.tab控件又没有显示遮罩的设置(至少本菜是没有找到), Google了一下,根据另一个兄台写的方法,拿来改造了一 ...
随机推荐
- 在使用Myeclipse时,用Tomcat添加部署项目的时候报错,或启动tomcat报错
the selected server is enabled,but is not configured properly.deployment to it will not be permitted ...
- linux ll 命令各列的含义
linux ll 命令各列的含义:
- HDU 3853:LOOPS(概率DP)
http://acm.split.hdu.edu.cn/showproblem.php?pid=3853 LOOPS Problem Description Akemi Homura is a M ...
- C#Winform常引用的库
1.DevExpress:引用其下的不同DLL,可操作使用不同的控件 2.IrisSkin2:引用对应的DLL后,代码如下 private Sunisoft.IrisSkin.SkinEngine s ...
- 【转】Eclipse插件大全介绍及下载地址
转载地址:http://developer.51cto.com/art/200906/127169.htm 尚未一一验证. eclipse插件大全介绍,以及下载地址 Eclipse及其插件下载网址大全 ...
- Check the difficulty of problems
Check the difficulty of problems Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5830 Acc ...
- sql server 添加字段并且赋默认值和说明
select soct.Captcha,CreateOn,* from SceneryOrderCheckTicket soctright join (SELECT Captcha,convert(c ...
- nylg 小M的因子和
小M的因子和 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 小M在上课时有些得意忘形,老师想出道题目难住他.小M听说是求因子和,还是非常得意,但是看完题目是求A的B ...
- Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析
一.前言 之前介绍了Android直播视频中一种视频源数据采集:摄像头Camera视频数据采集分析 中介绍了利用Camera的回调机制,获取摄像头的每一帧数据,然后进行二次处理进行推流.现在我们在介绍 ...
- 解决json_encode中文UNICODE转码问题
用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式,如果想汉字不进行转码,这里提供三种方法 .升级PHP,在PHP5., 这个问题终于得以解 ...