.........
.........CComPtr <AboutWebEvent> pAboutWebEvent;//"AboutWebEvent"是一个从IDispatch派生的类接口,作为新的接口for( long i=0;i<nFormCount;i++ )
{
IDispatch *pDisp = NULL; //取得第 i 项表单
hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp ); if ( FAILED( hr ) ) continue; CComQIPtr < IHTMLFormElement > spFormElement = pDisp;
pDisp->Release(); CComVariant vEvent;
vEvent.pdispVal = ( IDispatch* )pAboutWebEvent;
vEvent.vt = VT_DISPATCH;
IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
DWORD pdwCookie;
hr=spFormElement->QueryInterface( IID_IConnectionPointContainer,(void**)&pCPC );
if ( hr == S_OK )
{
hr = pCPC->FindConnectionPoint(DIID_HTMLFormElementEvents2,&pCP);
if ( hr == S_OK )
{
hr = pCP->Advise((IUnknown*)&vEvent,&pdwCookie);
}
pCPC->Release();
}}
其中的AboutWebEvent是一个从IDispatch派生的类接口,作为新的接口。如下:
class AboutWebEvent : public IDispatch
{
public:
AboutWebEvent():m_dwRef(1)
{};
public:
~AboutWebEvent(){}; DWORD m_dwRef;
// IUnknown
STDMETHOD(QueryInterface)(const struct _GUID &riid,void ** ppv){
*ppv = NULL; if (IID_IUnknown == riid)
{
*ppv = (LPUNKNOWN)this;
AddRef();
return NOERROR;
}
else if (IID_IDispatch == riid)
{
*ppv = (IDispatch*)this;
AddRef();
return NOERROR;
}
else
{
return E_NOTIMPL;
}
}
ULONG __stdcall AddRef(void){
return ++m_dwRef;
}
ULONG __stdcall Release(void){
if (--m_dwRef == 0)
{
delete this;
return 0;
}
return m_dwRef;
}
// IDispatch
STDMETHOD(GetTypeInfoCount)(unsigned int *){
TRACE("GetTypeInfoCount\n"); return E_NOTIMPL;
}
STDMETHOD(GetTypeInfo)(unsigned int,unsigned long,struct ITypeInfo ** ){
TRACE("GetTypeInfo\n"); return E_NOTIMPL;
}
STDMETHOD(GetIDsOfNames)(const IID &,LPOLESTR *,UINT,LCID,DISPID *){
TRACE("GetIDsOfNames\n"); return E_NOTIMPL;
}
STDMETHOD(Invoke)(DISPID dispID,const struct _GUID &,unsigned long,unsigned short,struct tagDISPPARAMS * pParams,struct tagVARIANT *,struct tagEXCEPINFO *,unsigned int *)
{
switch( dispID )
{
case DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT:
::AfxMessageBox("提交表单");
break;}
return NOERROR;
}
};
为什么程序执行没反应,根本就执行不到Invoke里面来(加断点)
执行到hr = pCP->Advise((IUnknown*)&vEvent,&pdwCookie);
这一句时,pdwCookie的值为0,意思是说连接无效?
由于我对COM可连接对象了解甚少,也不知道上面这些代码(用别人的)结构对不对,
大哥们给看看啊!!
.........CComPtr <AboutWebEvent> pAboutWebEvent;//"AboutWebEvent"是一个从IDispatch派生的类接口,作为新的接口for( long i=0;i<nFormCount;i++ )
{
IDispatch *pDisp = NULL; //取得第 i 项表单
hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp ); if ( FAILED( hr ) ) continue; CComQIPtr < IHTMLFormElement > spFormElement = pDisp;
pDisp->Release(); CComVariant vEvent;
vEvent.pdispVal = ( IDispatch* )pAboutWebEvent;
vEvent.vt = VT_DISPATCH;
IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
DWORD pdwCookie;
hr=spFormElement->QueryInterface( IID_IConnectionPointContainer,(void**)&pCPC );
if ( hr == S_OK )
{
hr = pCPC->FindConnectionPoint(DIID_HTMLFormElementEvents2,&pCP);
if ( hr == S_OK )
{
hr = pCP->Advise((IUnknown*)&vEvent,&pdwCookie);
}
pCPC->Release();
}}
其中的AboutWebEvent是一个从IDispatch派生的类接口,作为新的接口。如下:
class AboutWebEvent : public IDispatch
{
public:
AboutWebEvent():m_dwRef(1)
{};
public:
~AboutWebEvent(){}; DWORD m_dwRef;
// IUnknown
STDMETHOD(QueryInterface)(const struct _GUID &riid,void ** ppv){
*ppv = NULL; if (IID_IUnknown == riid)
{
*ppv = (LPUNKNOWN)this;
AddRef();
return NOERROR;
}
else if (IID_IDispatch == riid)
{
*ppv = (IDispatch*)this;
AddRef();
return NOERROR;
}
else
{
return E_NOTIMPL;
}
}
ULONG __stdcall AddRef(void){
return ++m_dwRef;
}
ULONG __stdcall Release(void){
if (--m_dwRef == 0)
{
delete this;
return 0;
}
return m_dwRef;
}
// IDispatch
STDMETHOD(GetTypeInfoCount)(unsigned int *){
TRACE("GetTypeInfoCount\n"); return E_NOTIMPL;
}
STDMETHOD(GetTypeInfo)(unsigned int,unsigned long,struct ITypeInfo ** ){
TRACE("GetTypeInfo\n"); return E_NOTIMPL;
}
STDMETHOD(GetIDsOfNames)(const IID &,LPOLESTR *,UINT,LCID,DISPID *){
TRACE("GetIDsOfNames\n"); return E_NOTIMPL;
}
STDMETHOD(Invoke)(DISPID dispID,const struct _GUID &,unsigned long,unsigned short,struct tagDISPPARAMS * pParams,struct tagVARIANT *,struct tagEXCEPINFO *,unsigned int *)
{
switch( dispID )
{
case DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT:
::AfxMessageBox("提交表单");
break;}
return NOERROR;
}
};
为什么程序执行没反应,根本就执行不到Invoke里面来(加断点)
执行到hr = pCP->Advise((IUnknown*)&vEvent,&pdwCookie);
这一句时,pdwCookie的值为0,意思是说连接无效?
由于我对COM可连接对象了解甚少,也不知道上面这些代码(用别人的)结构对不对,
大哥们给看看啊!!
把CComVariant*强制转换成IUnknown*,这句编译能通过?
pDisp->Release(); "
不能释放把,应该是同一个地址,释放了,上面也没了
可以编译通过啊 ,如果不加(IUnknown*),编译的时候出错,说是cannot convert 参数1 from'ATL::CComVariant *__w64' to 'IUnknown'
应该不会吧,因为已经CComQIPtr < IHTMLFormElement > spFormElement = pDisp 了,以后用的就是spFormElement了
//DOMEventHandler.h#pragma once
#include "oaidl.h"
#include "ExDispID.h"
class CDOMEventHandler :
public IDispatch{
public:
CDOMEventHandler(void);
public:
~CDOMEventHandler(void); HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject);
DWORD __stdcall AddRef();
DWORD __stdcall Release();
STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo) { return E_NOTIMPL; }
STDMETHOD(GetTypeInfo)(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR* ppTInfo) { return E_NOTIMPL; }
STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId) { return S_OK; }
STDMETHOD(Invoke)(DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS* pDispParams
, VARIANT* pVarResult
, EXCEPINFO * pExcepInfo
, UINT * puArgErr
); };
//DOMEventHandler.cpp#include "StdAfx.h"
#include "DOMEventHandler.h"
#include "ExDispID.h"
#include <mshtmdid.h>
CDOMEventHandler::CDOMEventHandler(void)
{
}CDOMEventHandler::~CDOMEventHandler(void)
{
}HRESULT __stdcall CDOMEventHandler::QueryInterface(REFIID riid, void** ppvObject)
{
*ppvObject = NULL;
if (IsEqualGUID(riid, IID_IUnknown))
*ppvObject = reinterpret_cast<void**>(this);
if (IsEqualGUID(riid, IID_IDispatch))
*ppvObject = reinterpret_cast<void**>(this);
if (*ppvObject)
{
((IUnknown*)*ppvObject)->AddRef();
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
DWORD __stdcall CDOMEventHandler::AddRef()
{
return 1;
}
DWORD __stdcall CDOMEventHandler::Release()
{
return 0;
}
HRESULT CDOMEventHandler::Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO * pExcepInfo,
UINT * puArgErr)
{
::AfxMessageBox("进入Invoke");
if (dispIdMember == DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT)
{
::AfxMessageBox("提交页面");
}
return S_OK;
} 建立连接:
IDispatch *pDisp = NULL; //取得第 i 项表单
hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp );
if ( FAILED( hr ) ) continue; CComQIPtr < IHTMLFormElement > spFormElement = pDisp;
pDisp->Release();
CComPtr <CDOMEventHandler> pAboutWebEvent;
CComVariant vEvent;
vEvent.pdispVal = ( IDispatch* )pAboutWebEvent;
//vEvent.vt = VT_DISPATCH; IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
DWORD pdwCookie = NULL;
hr=spFormElement->QueryInterface( IID_IConnectionPointContainer,(void**)&pCPC );
if ( hr == S_OK )
{
hr = pCPC->FindConnectionPoint(DIID_HTMLFormElementEvents2,&pCP);
if ( hr == S_OK )
{
HRESULT hr1;
hr1 = pCP->Advise((IUnknown*)&vEvent,&pdwCookie);//(IUnknown*)
//Invoke();
}
pCPC->Release();还是不行,Invoke没有被调用
是全局的,在.cpp开头就声明了,我只是想把下面的几句联系到一块儿,就那样写了,我的错!!!
hr = pCP->Advise((IUnknown*)&vEvent,&pdwCookie);
这句改为CComQIPtr<IUnknown, &IID_IUnknown> spUnk = pAboutWebEvent;
hr = pCP->Advise(spUnk ,&pdwCookie);
也不行啊,还是一样的情况,不知道我那个类写的有没有问题(参照)pdwCookie的值始终为0, spUnk调试之后的值为{0X00000000}
你这里没有创建CDOMEventHandler的对象!! 当然spUnk是空指针了~
CComQIPtr<IUnknown, &IID_IUnknown> spUnk = pAboutWebEvent;
执行完这句之后,pAboutWebEvent的值也是{0X00000000}
咋看不明白呢,这一句不是在.cpp开头儿已经创建为全局的了嘛
CDOMEventHandler pAboutWebEvent;(全局)
CComQIPtr<IUnknown, &IID_IUnknown> spUnk = pAboutWebEvent;这一句不能要了,还得改回原来的
CComVariant vEvent;
vEvent.pdispVal = ( IDispatch* )&pAboutWebEvent; //CComQIPtr<IUnknown, &IID_IUnknown> spUnk = pAboutWebEvent;
IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
DWORD pdwCookie = NULL;
hr=spFormElement->QueryInterface( IID_IConnectionPointContainer,(void**)&pCPC );
if ( hr == S_OK )
{
hr = pCPC->FindConnectionPoint(DIID_HTMLFormElementEvents2,&pCP);
if ( hr == S_OK )
{
HRESULT hr1;
hr1 = pCP->Advise((IUnknown*)&vEvent,&pdwCookie);
//hr1 = pCP->Advise(spUnk,&pdwCookie);
if ( FAILED( hr1 ) ) ::AfxMessageBox("bbb");
}
pCPC->Release();这在以前已经测试过,结果自然还是不会调用Invoke,这种情况下,pAboutWebEvent不为{0X00000000},而是{m_dwRef=1},其中m_dwRef是在类中的一个计数器吧,但是,vEvent的值为{VT_EMPTY}, pdwCookie的值还依然为0———无效的连接
#include "DOMEventHandler.h"
#include "ExDispID.h"
#include <mshtmdid.h>
CDOMEventHandler::CDOMEventHandler(void):m_dwRef(1)
{
}CDOMEventHandler::~CDOMEventHandler(void)
{
} DWORD m_dwRef;HRESULT __stdcall CDOMEventHandler::QueryInterface(const struct _GUID &riid,void ** ppv){
*ppv = NULL; if (IID_IUnknown == riid)
{
*ppv = (LPUNKNOWN)this;
AddRef();
return NOERROR;
}
else if (IID_IDispatch == riid)
{
*ppv = (IDispatch*)this;
AddRef();
return NOERROR;
}
else
{
return E_NOTIMPL;
}
}
DWORD __stdcall CDOMEventHandler::AddRef()
{
//return 1;
return ++m_dwRef;
}
DWORD __stdcall CDOMEventHandler::Release()
{
//return 0;
if (--m_dwRef == 0)
{
delete this;
return 0;
}
return m_dwRef;
}
HRESULT CDOMEventHandler::Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO * pExcepInfo,
UINT * puArgErr)
{
::AfxMessageBox("进入Invoke");
if (dispIdMember == DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT)
{
::AfxMessageBox("提交页面");
}
return S_OK;
}
//把下面两句
//CComVariant vEvent;
//vEvent.pdispVal = ( IDispatch* )pAboutWebEvent;
//改为:
CComQIPtr<IUnknown, &IID_IUnknown> spUnk = &pAboutWebEvent;
IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
DWORD pdwCookie = NULL;
hr=spFormElement->QueryInterface( IID_IConnectionPointContainer,(void**)&pCPC );
if ( hr == S_OK )
{
hr = pCPC->FindConnectionPoint(DIID_HTMLFormElementEvents2,&pCP);
if ( hr == S_OK )
{
//把下面一句 //hr= pCP->Advise((IUnknown*)&vEvent,&pdwCookie);
//改为
hr= pCP->Advise(spUnk,&pdwCookie);
if ( FAILED( hr1 ) )
::AfxMessageBox("Advise调用失败");
}
pCPC->Release();
}
在上述代码中,我估计是hr= pCP->Advise((IUnknown*)&vEvent,&pdwCookie);这一句出了问题,jameshooo大哥说的很有道理,不应该把CComVariant*强制转换成IUnknown*,
经过修正后也根本不需要CComVariant但是,类CDOMEventHandler中的Invoke 依然没有被调用,连接部分执行完毕后直接就推出程序了,切盼大哥们指教
-----------
这句为啥不能要了呢?
改成这样:
CDOMEventHandler pAboutWebEvent;(全局)
CComQIPtr<IUnknown, &IID_IUnknown> spUnk = &pAboutWebEvent;
hr= pCP->Advise(spUnk,&pdwCookie);
就可以!
-------------
你连接成功后,需要去触发submit事件
skyxie大哥能帮我实现不?这个我可确实不会另外,我的工程原意是当用户用鼠标点击网页中的“提交”按钮,系统响应DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT事件,当程序获取此网页的DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT事件后,再进行其他的操作,我是这样想的,不知与skyxie大哥的意思“连接成功后,需要去触发submit事件”是否一致,望skyxie大哥明示啊!!!