描述:
有些时候发现documentcomplete会被多次触发。
msdn里说如果页面含有框架的话就可能这样。
This event's pDisp parameter is the same as the IDispatch interface pointer of the frame in which this event fires.
In the loading process, the highest level frame (which is not necessarily the top-level frame) fires the final DWebBrowserEvents2::DocumentComplete event. At this time, the pDisp parameter will be the same as the IDispatch interface pointer of the highest level frame.
它说函数的第一个参数pDisp和the IDispatch interface pointer of the frame in which this event fires是一样的。
最高层的框架会最后产生这个事件,而且它的pDisp和the IDispatch interface pointer of the highest level frame是一样的。
可是在Invoke里加上这段后发现两个指针却是不相等的
case DISPID_BEFORENAVIGATE2:{
m_pDisp=pDispParams->rgvarg[0].pdispVal;
ATLTRACE("m_pDisp=0x%x\n",m_pDisp);
}
case DISPID_DOCUMENTCOMPLETE:
{
IDispatch* pDisp;
IHTMLDocument2 *pDoc;
m_pWebBrowser2->get_Document(&pDisp);
IDispatch *pCurDisp=pDispParams->rgvarg[0].pdispVal;
ATLTRACE("0x%x,0x%x\n",m_pDisp,pCurDisp);
if(pCurDisp==m_pDisp) //if(pDisp==pCurDisp)
ATLTRACE("equal\n");
else
ATLTRACE("not equal\n");
break;
}
看起来应该是上面这段代码有问题。应该如何改呢?
解决方案1:
不是只因为 页面含有框架 会多次 documentcomplete
你连接点多次,也会多次调用 documentcomplete
//处理navigate complete,查阅相关KB 如何判断文档下载完成
STDMETHODIMP CSpyIEEx::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams, VARIANT* pvarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
// Through this dispatch interface, we'll receive all browser events
// Event arguments are listed before each case statement
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!pDispParams)
return E_INVALIDARG;
CComPtr<IDispatch> spDisp;
HRESULT hr;
switch (dispidMember)
{
// [0]: Cancel flag - VT_BYREF|VT_BOOL
// [1]: HTTP headers - VT_BYREF|VT_VARIANT
// [2]: Address of HTTP POST data - VT_BYREF|VT_VARIANT
// [3]: Target frame name - VT_BYREF|VT_VARIANT
// [4]: Option flags - VT_BYREF|VT_VARIANT
// [5]: URL to navigate to - VT_BYREF|VT_VARIANT
// [6]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
//监视IE BEFORENAVIGATE2事件
case DISPID_BEFORENAVIGATE2:
{
// Deactivate keyboard hook
IHTMLDocument2* pDoc2=NULL;
m_pDoc2=pDoc2;
}
break;
// [0]: URL navigated to - VT_BYREF|VT_VARIANT
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
case DISPID_NAVIGATECOMPLETE:
// m_pDisp=pDispParams->rgvarg[0].pdispVal;
break;
// [0]: New status bar text - VT_BSTR
//
/*
case DISPID_STATUSTEXTCHANGE:
break;
*/
// [0]: Maximum progress - VT_I4
// [1]: Amount of total progress - VT_I4
//
/*
case DISPID_PROGRESSCHANGE:
break;
*/
// [0]: Document URL - VT_BYREF|VT_VARIANT
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
case DISPID_DOCUMENTCOMPLETE:
{
// Temporarily disable keyboard hook
IDispatch*disp= pDispParams->rgvarg[1].pdispVal;
if(m_spWebBrowser2 == disp )
{
// Fill in form if necessary
try
{
// Get the WebBrowser's document object
hr = m_spWebBrowser2->get_Document(&spDisp);
if (SUCCEEDED(hr) && spDisp && m_spWebBrowser2)
{
...
}
...