我有一个问题,就像下沉 DWebBrowserEvents2 事件中的 JimEvans 似乎挂起编程导航但我无法理解答案,有人可以告诉我更多信息吗?
我正在通过普通 C++ 操作 IE Explorer。一些代码是从 Codeproject 复制而来的。但是当我处理事件时,我的 IE 挂起,并且在我的主函数完成之前我无法获得 DISPID_NAVIGETCOMPLETE 事件。
我的代码如下:
#include <afxwin.h>
#include <afxdisp.h>
#include <iostream>
#include <MsHTML.h>
#include <Exdisp.h>
#include <ExDispid.h>
class IE_Events_Sinker : public DWebBrowserEvents2
{
public:
// No constructor or destructor is needed
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid,void **ppvObject);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IDispatch methods
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo);
STDMETHODIMP GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo);
STDMETHODIMP GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId);
STDMETHODIMP Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,
DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr);
};
IE_Events_Sinker IESinker;
STDMETHODIMP IE_Events_Sinker::Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pDispParams,
VARIANT FAR* pVarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr )
{
switch(dispIdMember)
{
case DISPID_NAVIGATEERROR:
{
//Extract the status code from the DISPPARAMS structure
VARIANT * vt_statuscode = pDispParams->rgvarg[1].pvarVal;
DWORD dwStatusCode = vt_statuscode->lVal;
//Extract the event's IDispatch pointer
IDispatch *pdispFiredEvent = pDispParams->rgvarg[4].pdispVal;
printf("Status Code: %d\n", dwStatusCode);
break;
}
case DISPID_NAVIGATECOMPLETE2:
printf("Navigate Complete!\n");
break;
case DISPID_BEFORENAVIGATE2:
printf("Before Navigate is fired!\n");
break;
default:
//MessageBox(NULL, L"A Message", NULL, NULL);
printf("A Message !\n the dispIdMemberis %d\n", dispIdMember);
break;
}
return S_OK;
}
STDMETHODIMP IE_Events_Sinker::QueryInterface(REFIID riid,void **ppvObject)
{
// Check if ppvObject is a valid pointer
if(IsBadWritePtr(ppvObject,sizeof(void*))) return E_POINTER;
// Set *ppvObject to NULL
(*ppvObject)=NULL;
// See if the requested IID matches one that we support
// If it doesn't return E_NOINTERFACE
if(!IsEqualIID(riid,IID_IUnknown) && !IsEqualIID(riid,IID_IDispatch) && !IsEqualIID(riid,DIID_DWebBrowserEvents2)) return E_NOINTERFACE;
// If it's a matching IID, set *ppvObject to point to the global EventSink object
(*ppvObject)=(void*)&IESinker;
return S_OK;
}
STDMETHODIMP_(ULONG) IE_Events_Sinker::AddRef()
{
return 1; // We always have just one static object
}
STDMETHODIMP_(ULONG) IE_Events_Sinker::Release()
{
return 1; // Ditto
}
// We don't need to implement the next three methods because we are just a pure event sink
// We only care about Invoke() which is what IE calls to notify us of events
STDMETHODIMP IE_Events_Sinker::GetTypeInfoCount(UINT *pctinfo)
{
UNREFERENCED_PARAMETER(pctinfo);
return E_NOTIMPL;
}
STDMETHODIMP IE_Events_Sinker::GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)
{
UNREFERENCED_PARAMETER(iTInfo);
UNREFERENCED_PARAMETER(lcid);
UNREFERENCED_PARAMETER(ppTInfo);
return E_NOTIMPL;
}
STDMETHODIMP IE_Events_Sinker::GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)
{
UNREFERENCED_PARAMETER(riid);
UNREFERENCED_PARAMETER(rgszNames);
UNREFERENCED_PARAMETER(cNames);
UNREFERENCED_PARAMETER(lcid);
UNREFERENCED_PARAMETER(rgDispId);
return E_NOTIMPL;
}
int main()
{
HRESULT hr;
IWebBrowser2* IWbr;
IConnectionPointContainer* pCPContainer;
IConnectionPoint* m_pConnectionPoint;
CoInitialize(NULL);
//hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&IWbr);
hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&IWbr);
IWbr->put_Visible(TRUE);
hr = IWbr->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPContainer);
hr = pCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pConnectionPoint);
//Important Point!
DWORD m_dwCookie;
m_pConnectionPoint->Advise(&IESinker, &m_dwCookie);
COleVariant vtEmpty;
BSTR url2 = SysAllocString(L"http://www.qq.com/");
IWbr->Navigate(url2, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);
Sleep(20000);
//hr = IWbr->Quit();
//while(FAILED(hr))
//{
//a++;
//hr = IWbr->Quit();
//}
//printf("shut down %d times\n", a);
m_pConnectionPoint->Unadvise(m_dwCookie);
m_pConnectionPoint->Release();
IWbr->Release();
pCPContainer->Release();
CoUninitialize();
}