方法一: 使用MFC映射宏,使用 CCmdTartget 子类为EventSink类
.H文件
1. DECLARE_DISPATCH_MAP()
2. DECLARE_INTERFACE_MAP()
.CPP文件
1. BEGIN_DISPATCH_MAP(当前类, 父类) //实现本地函数与组件中的函数映射
DISP_FUNCTION_ID(当前类, "组件中的函数名", 函数DISP_ID, 本地函数, VARIANT的返回类型, VARIANT的参数类型)
...
END_DISPATCH_MAP()
2. BEGIN_INTERFACE_MAP(当前类,父类) //映射事件接口
INTERFACE_PART(本地类, 事件接口ID, Dispatch) //这里Dispatch为CCmdTart类的一个结构,该宏填充这个结构
...
END_INTERFACE_MAP()
3. 在stdafx.h中加入
#include //用到 AfxConnectionAdvise 和AfxConnectionUnadvise
#import ".../组件名.tlb" no_namespace named_guids //导入组件类型库
no_namespace 没有命名空间
named_guids 导入组件GUID名称 (使用了该参数后不需要再include组件的_i.c文件)
4.
初始化Dispatch结构,实例化组件对象并建立事件连接
EnableAutomation(...); //同上面的宏一起实现了IDispatch接口
AfxConnectionAdvise(事件源/*组件对象*/, DIID__I..., GetIDispatch(FALSE)/*得到Dispatch*/, FALSE, &m_dwCookie)
...
5. 取消连接, 消毁对象
AfxConnectionUnadvise(...) //取消连接
对象智能指针.Release()
对象智能指针 = NULl;
方法二: 使用ATL映射宏,单独的EventSink类,该类继承 IDsipEventImpl
1. stdafx.h 加入
#include
#include
#import ".../组件名.tlb" no_namespace named_guids
2. CEventSink类
.H 文件
1. 使用ATL宏定义函数信息结构
_ATL_FUNCTION_INFO FuncInfo =
{
CC_STDCALL, //调用方式
VT_EMPTY, //返回类型
1, //参数个数
{VT_I4} //参数类型表
};
2. ATL宏映射事件函数
BEGIN_SINK_MAP(CEventSink)
SINK_ENTRY_INFO(1, DIID_I..., DISP_ID, LocalFunc, &FuncINfo)
...
END_SINK_MAP()
3.
实例化组件对象和EventSink对象
用EventSink对象或AtlAdvise函数建立连接: EventSink->Advise(...) EventSink->DispEventAdvise(...) AtlAdvise(...)
...
4.
取消连接, 消毁对象
示例:
#ifndef __EVENTSINK_H
#define __EVENTSINK_H
namespace //作用??
{
static const int DISPID_SHOW = 1;
static const int DISPID_SHOW2 = 2;
_ATL_FUNC_INFO OnShowInfo =
{
CC_STDCALL, //calling conv...
VT_EMPTY,//return value...
0 ,//number of arguments...
NULL//argumnent types...
};
_ATL_FUNC_INFO OnShow2Info =
{
CC_STDCALL, //calling conv...
VT_EMPTY,//return value...
1 ,//number of arguments...
{ VT_I2}//argumnent types...
};
}
class CEventSink : public IDispEventImpl<1, CEventSink, &DIID__IAtlTest2Events, &LIBID_TEST2Lib>
{
public:
CEventSink(){};
virtual ~CEventSink(){};
void __stdcall OnShow(); //没有参数的情况
void __stdcall OnShow2(short);//有参数的情况
//必须要用SINK_ENTRY_INFO,必须指定参数信息
BEGIN_SINK_MAP(CEventSink)
SINK_ENTRY_INFO(1,DIID_ISimpleCOMEvents,DISPID_SHOW,OnShow,&OnShowInfo)
SINK_ENTRY_INFO(1,DIID_ISimpleCOMEvents,DISPID_SHOW2,OnShow2,&OnShow2Info)
END_SINK_MAP()
};
#endif
方法三:自定义EventSink,从IDispatch派生,实现所有的虚方法,在Invoke函数中根据DISP_ID处理回调