事件接收器的实现
方法一: 使用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處理回調
總結
- 上一篇: mfc工程中添加com接口支持
- 下一篇: 字符串转换 - 应该熟练掌握的东西