关闭

初识统一事件模型之COM连接点

标签: vc++interfacehookclassc#module
1940人阅读 评论(0) 收藏 举报
学习C#的时候,最喜欢的就是event关键字,因为事件处理变得很轻松。以往在C++里,我们一般是使用回调函数或者虚函数(接口),虽然也挺方便,但是如果有多个事件接收者就比较麻烦了,而且每个人实现的回调方式都不一样。在COM编程模型里的连接点也很好,允许多个事件接收者,甚至利用COM的机制跨进程回调通知,可惜实现太负责,调用也麻烦。最好还是像C#的event关键字,清晰明了。

在尝试使用Attribute编写COM组件的时候,发现原来微软在VC++里增加很多关键字,用以简化和统一事件模型。这样使用同样的语法,就可以同时处理Native,COM和Managed的事件!

为了利用VC++的这个新特性(好像2000年就出来了,不算新啦,见笑见笑),今天郁闷了一天,现在终于搞定了,总结一下。

事件的定义和触发

__interface _IMyEventSink
{
    HRESULT SomethingHappened();
};

[coclass,event_source(com)]    //关键是event_source(com)
class MySourceObject
{
  __event __interface _IMyEventSink;    //跟C#的语法一样

  void DoSomething()
  {
     __raise SomethingHappened();    //直接调用事件接口里的方法。
  }
};

事件的接收,有两种办法,你可以单独接收某个事件(接口里的一个方法),或者接收事件接口里的所有方法。前者比较灵活,后者比较省事。

#import "mycom.dll"  no_namespace embedded_idl

//如果用#import引入类型库,一定要记得带上embedded_idl参数。为了这个,我可郁闷了很久啊。
//但是这个参数加上后,带来一个副作用,那就是那些封装函数没有了,比如属性的访问函数put_name不能直接用name访问了。

IUnknown* pSourceObject;

...

//下面只处理一个事件
[event_receiver(com)]
class _MyEventHandler
{
public:
    void Advise(IUnknown* pSource)
    {
         __hook(&_IMyEventSink::SomethingHappened,pSource,&_MyEventHandler::SomethingHappenedXXX);
    }

       HRESULT SomethingHappenedXXX()    //函数名不需要跟事件方法相同
       {
          //...
       }
};

_MyEventHandler handler;
handler.Advise(pSourceObject);


//下面处理所有事件
[module(name="mymodule")];    //必须

[coclass,uuid("..."),event_receiver(com,true)]    //必须是一个COM对象
class _MyEventHandler :public  _IMyEventSink    //必须从_IMyEventSink派生
{
public:
    void Advise(IUnknown* pSource)
    {
        __hook(_IMyEventSink,pSource);
    }

       HRESULT SomethingHappened()    //原型必须与_IMyEventSink里的方法一致
       {
          //...
       }
};

CComObject<_MyEventHandler>* pHandler=new CComObject<_MyEventHandler>;
pHandler->AddRef();
pHandler->Advise(pSourceObject);


如此看来,COM的连接点还是比较容易实现的。

参考文档:
http://msdn.microsoft.com/msdnmag/issues/01/04/Attributes/default.aspx
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:238163次
    • 积分:4215
    • 等级:
    • 排名:第7541名
    • 原创:127篇
    • 转载:7篇
    • 译文:7篇
    • 评论:56条
    最新评论