COM——事件接收器实现方法总结

方法一:使用MFC映射宏,从CCmdTartget派生子类EventSink

1.  .h文件中申明接口、分派ID映射

DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()

2.   .cpp文件实现接口、分派ID映射

// 映射分派ID
BEGIN_DISPATCH_MAP(cThisClass, CBaseClass)
     DISP_FUNCTION_ID(CThisClass, 
            " ComFunc " ,
             DISP_ID, 
              LocalFuncName, 
              VARIANT_RETURN_TYPE, 
              VARIANT_PARAMS_TYPE)
END_DISPATCH_MAP()
      
// 映射事件接口
BEGIN_INTERFACE_MAP(CThisClass,CBaseClass)    
     INTERFACE_PART(CThisClass, DIID_IEventXX, Dispatch) 
// 这里Dispatch为CCmdTart类的一个结构,该宏填充这个结构
END_INTERFACE_MAP()

3.  #import ".../组件名.tlb" no_namespace named_guids no_namespace

4. 初始化COM库、Dispatch结构并建立连接

      CoInitialize(NULL);
EnableAutomation();     // 同上面的宏一起实现了IDispatch接口
    AfxConnectionAdvise(ComObject ,  DIID__IEventXX,  GetIDispatch(FALSE) ,  FALSE,  & m_dwCookie);

5.  实现映射函数(LocalFuncName)

6.  卸载COM库、取消连接

AfxConnectionUnadvise()   
      CoUnInitialize();


方法二:  使用ATL映射宏,继承IDsipEventImpl

1.   #import ".../组件名.tlb" no_namespace named_guids

2.  实现事件接收类CEventSink

      a.  使用ATL宏定义函数信息结构      

_ATL_FUNCTION_INFO FuncInfo  =
{
     CC_STDCALL,  
// 调用方式
     VT_EMPTY,        // 返回类型
      1 ,                           // 参数个数
    {VT_I4}                 // 参数类型表
}
;

      b.   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处理回调 (代码略)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值