如何监听当前执行中IE的onDocumentComplete事件
各位安好
目前我想写一支程式hook住当前执行中的IE,当onDocumentComplete事件发生时显示讯息
第一种我最希望的是直接用TWebBrowser元件去attach当前执行中的IE,这样我可以直接对TWebBrowser操作,但我找不到方法这么做
第二种是自己用IWebBrowser2去attach IE
我已经用了下面的方法去attach 当前执行中的IE
#include "atl/atlbase.h"
#include <exdisp.h>
#include <mshtml.h>
CComQIPtr<IWebBrowser2> pCurIE;
void __fastcall TForm4::Button3Click(TObject *Sender)
{
bool SuccessToHook = false;
CComPtr<IShellWindows> m_spSHWinds;
if (FAILED(m_spSHWinds.CoCreateInstance( __uuidof( ShellWindows)))){
return ;
}
LONG nCount;
m_spSHWinds->get_Count( &nCount);
ShowMessage(nCount);
for (int i = 0; i < nCount; i++) {
CComPtr<IDispatch> pDisp;
m_spSHWinds->Item( CComVariant(i), &pDisp);
CComQIPtr<IWebBrowser2> pIE(pDisp);
if (pIE == NULL){
continue ;
}
CComPtr<IDispatch> pDispDoc;
pIE->get_Document(&pDispDoc);
CComQIPtr<IHTMLDocument2> pHtmlDoc(pDispDoc);
if (pHtmlDoc){
pCurIE = pIE;
SuccessToHook = true;
break ;
}
}
ShowMessage(SuccessToHook ? "Success to hook." : "Failed to hook." );
}
现在我可以用pCurIE去浏览不同的网页,也可以读取当前document,但不知道怎样才能和操作TWebBrowser一样当发生onDocumentComplete事件时做操作
我对于Com的操作很不熟...
不知道各位有解决的办法吗?谢谢
[解决办法]
参考我的解决办法
h文件
#include <ExDispid.h>
#include <Exdisp.h> //如果提示重复定义的话 把这个删掉
class WebBrwoser2EventListener : public IDispatch //DWebBrowserEvents2
{
private:
void _stdcall BeforeNavigate2(IDispatch *pDisp,
OleVariant &URL, OleVariant &Flags, OleVariant &TargetFrameName,
OleVariant &PostData, OleVariant &Headers, WordBool &Cancel);
void _stdcall DocumentComplete(IDispatch *pDisp, OleVariant &URL);
void _stdcall DownloadBegin();
void _stdcall DownloadComplete();
void _stdcall ProgressChange(int Progress, int ProgressMax);
void _stdcall NewWindow3(VARIANT_BOOL* Cannel,BSTR url);
public: // IDispatch methods
STDMETHOD(QueryInterface)( REFIID riid, void **ppvObject)
{
HRESULT hr = E_NOINTERFACE;
if (riid == __uuidof(IDispatch))
{
*ppvObject = (IDispatch*)this;
AddRef();
hr = S_OK;
}
else if (riid == __uuidof(DWebBrowserEvents2))
{
*ppvObject = (IDispatch*)this; // DWebBrowserEvents2*
AddRef();
hr = S_OK;
}
return hr;
}
STDMETHODIMP_(ULONG) AddRef(void)
{
return 1;
};
STDMETHODIMP_(ULONG) Release(void)
{
return 1;
}
STDMETHOD(GetTypeInfoCount)(UINT*)
{
return E_NOTIMPL;
}
STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**)
{
return E_NOTIMPL;
}
STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR *rgszNames, UINT, LCID, DISPID *rgDispId)
{
return E_NOTIMPL;
}
STDMETHOD(Invoke)(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pDispParams,VARIANT FAR* pVarResult,EXCEPINFO FAR* pExcepInfo,unsigned int FAR* puArgErr)
{
HRESULT hr = S_OK;
if (dispIdMember == DISPID_BEFORENAVIGATE2)
{
WordBool Cancel=false;
IDispatch *pDisp=pDispParams->rgvarg[6].pdispVal;
OleVariant URL=OleVariant(pDispParams->rgvarg[5].pvarVal->bstrVal);
OleVariant Flags=OleVariant(pDispParams->rgvarg[4].pvarVal->bstrVal);
OleVariant TargetFrameName=OleVariant(pDispParams->rgvarg[3].pvarVal->bstrVal);
OleVariant PostData=OleVariant(pDispParams->rgvarg[2].pvarVal->bstrVal);
OleVariant Headers=OleVariant(pDispParams->rgvarg[1].pvarVal->bstrVal);
BeforeNavigate2(pDisp, URL, Flags, TargetFrameName, PostData, Headers, Cancel);
*pDispParams->rgvarg[0].pboolVal= Cancel? TRUE:FALSE;
}
if (dispIdMember == DISPID_DOCUMENTCOMPLETE)
{
OleVariant URL=OleVariant(pDispParams->rgvarg[0].pvarVal->bstrVal);
DocumentComplete(pDispParams->rgvarg[1].pdispVal, URL);
}
if (dispIdMember == DISPID_DOWNLOADBEGIN)
{
DownloadBegin();
}
if (dispIdMember == DISPID_DOWNLOADCOMPLETE)
{
DownloadComplete();
}
if (dispIdMember == DISPID_PROGRESSCHANGE)
{
ProgressChange(pDispParams->rgvarg[1].lVal,pDispParams->rgvarg[0].lVal);
}
if (dispIdMember == DISPID_NEWWINDOW3)
{
NewWindow3((pDispParams->rgvarg[3].pboolVal),(pDispParams->rgvarg->bstrVal));
}
return hr;
}
};
cpp文件
void _stdcall WebBrwoser2EventListener::BeforeNavigate2(IDispatch *pDisp,
OleVariant &URL, OleVariant &Flags, OleVariant &TargetFrameName,
OleVariant &PostData, OleVariant &Headers, WordBool &Cancel)
{
Form1->Memo1->Lines->Add(URL.bstrVal);
//Form1->Memo1->Lines->Add(Headers.bstrVal);
//Cancel=true;
}
//---------------------------------------
void _stdcall WebBrwoser2EventListener::DocumentComplete(IDispatch *pDisp, OleVariant &URL)
{
IWebBrowser2 *po=(IWebBrowser2 *)pDisp;
Form1->Memo1->Lines->Add(po->LocationName);
Form1->Memo1->Lines->Add(URL.bstrVal);
}
//---------------------------------------
void _stdcall WebBrwoser2EventListener::DownloadBegin()
{
//
}
//---------------------------------------
void _stdcall WebBrwoser2EventListener::DownloadComplete()
{
//
}
//---------------------------------------
void _stdcall WebBrwoser2EventListener::ProgressChange(int Progress, int ProgressMax)
{
//Form1->Memo1->Lines->Add((String)Progress+" "+(String)ProgressMax); //TEST
}
//---------------------------------------
调用的时候 要先获取 IWebBrowser2* pWeb;
然后
IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
DWORD dwCookie = 0;
pWeb->QueryInterface(IID_IConnectionPointContainer,(void**)&pCPC);
pCPC->FindConnectionPoint( DIID_DWebBrowserEvents2,&pCP);
WebBrwoser2EventListener* pEventListener=new WebBrwoser2EventListener;
pCP->Advise( (IUnknown*)(void*)pEventListener,&dwCookie);
//到这里 就已经可以从 pWeb 捕获定义的几个事件了
//pCP->Unadvise(dwCookie); //使用完成后要执行这个
//delete pEventListener;