通过IWebBrowser2的Navigate2来打开网页,怎样判断网页是否全部加载完毕

通过IWebBrowser2的Navigate2来打开网页,它会返回DISPID_DOCUMENTCOMPLETE表示显示完成。但如果一个页面有多个frame,则每个frame都会产生DISPID_DOCUMENTCOMPLETE事件,所以通过这个事件不能判断一个页面是否全部加载完毕了。后来通过google用以下办法解决了: 
void CCreateHTMLImage::DocumentComplete(LPDISPATCH pDisp, VARIANT* URL) 
{ 
IUnknown* pUnk; 
LPDISPATCH lpWBDisp; 
HRESULT hr; 

pUnk = m_pBrowserWnd.GetControlUnknown(); 
ASSERT(pUnk); 

hr = pUnk->QueryInterface(IID_IDispatch, (void**)&lpWBDisp); 
ASSERT(SUCCEEDED(hr)); 

if (pDisp == lpWBDisp ) 
{ 
TRACE("CCreateHTMLImage::DocumentComplete\n"); 
EndModalLoop(0); 
} 

lpWBDisp->Release(); 
} 
但是这样还是有问题,如果一个页面有图片,而且这个图片比较大,那么这个图片还没有加载完就会触发DISPID_DOCUMENTCOMPLETE事件。 
我是要做网页快照,这样一来,有时网页还没有完全加载完就快照了,那保存出来的见面快照图片中就会有空白的地方了。 
请问有办法知道网页是否全部加载完了吗?
网友回复:没办法,图片并不是在根文档下载完成时就一定下载完的,有两种办法: 
1、定时查询所有img元素的readyState,看看是否等于complete 
2、在DocumentComplete时扫描所有图片元素,挂接图片元素的onload事件,直到所有挂接的onload都被调用到。
网友回复:能写个例子吗?
网友回复:有个DocumentComplete事件,响应这个事件,然后找到docment对象,用get_all得到所有对象,然后枚举全部对象,查看state
网友回复:jameshooo的办法是比较好的办法.通过枚举iframes,查询readyState属性.
网友回复:TO jameshooo,能给个例子参考一下吗?
网友回复:在DocumentComplete中以及在定时器中: 
IWebBrowser2::get_Document --> IHTMLDocument3 
IHTMLDocument3::getElementsByTagName("img") --> IHTMLElementCollection 
IHTMLElementCollection::item --> IHTMLElement 
IHTMLElement::QueryInterface --> IHTMLImgElement 
IHTMLImgElement::get_readyState == "complete"? 

1)READYSTATE r;
HRESULT hr = IWebBrowser2::get_ReadyState(&r);
if (SUCCEEDED(hr) && r == READYSTATE_COMPLETE) {
...
}

2)if (SUCCEEDED(IWebBrowser2::Stop()) {
...
}

-------------------------
Navigate2后,可以查询组建状态,查询所使用的方法就是get_ReadyState。
如果READYSTATE等于READYSTATE_COMPLETE,就说明Navigate2所请求的数据已经DOWNLOAD完成了。

另外,还有个可以实时监控网页是否打开完毕的方法,准确说是IWebBrowser2的触发事件,原型:

BEGIN_EVENTSINK_MAP(MainDlg, CDialog)
ON_EVENT(MainDlg, IDC_EXPLORER1, 259, MainDlg::DocumentCompleteExplorer1, VTS_DISPATCH VTS_PVARIANT)
END_EVENTSINK_MAP()

void MainDlg::DocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT* URL)
{
//捕捉到网页完全下载/打开成功事件
}

原文地址:https://www.cnblogs.com/zdxster/p/1945898.html