模板类 IDispEventImpl 可用于在 ATL 类中提供连接点接收器支持。连接点接收器使类得以处理从外部 COM 对象引发的事件。这些连接点接收器是用事件接收映射(由类提供)来映射的。
若要正确地实现类的连接点接收器,必须完成以下步骤:
实现连接点接收器所涉及的步骤都是只通过修改类的头文件 (.h) 来完成的。
对于每一个希望处理其事件的外部对象,都必须导入类型库。此步骤定义可以处理的事件,并提供在声明事件接收映射时使用的信息。可以使用 #import 指令来完成此任务。在类的头文件 (.h) 中,为每个要支持的调度接口添加必需的 #import 指令行。
下面的示例导入外部 COM 服务器 (MyServer
) 的类型库:
#import "D://MyServer.dll" raw_interfaces_only, no_namespace, named_guids
注意 对每个要支持的外部类型库必须有一个单独的 #import 语句。
您已导入了每个调度接口的类型库,现在需要为每个外部调度接口分别声明 IDispEventImpl 接口。修改类的声明,为每个外部对象添加一个 IDispEventImpl 接口声明。有关参数的更多信息,请参见 IDispEventImpl。
下面的代码声明两个连接点接收器,一个用于自定义 IExtEvents1
和 IExtEvents2
接口,一个用于 CMyObj
类实现的 COM 对象:
public IDispEventImpl<0, CMyObj, &DIID__IExtEvents1, &LIBID_EXTEVENTS1Lib, 1, 0>, public IDispEventImpl<1, CMyObj, &DIID__IExtEvents2, &LIBID_EXTEVENTS2Lib, 1, 0>
为使事件通知能够由正确的函数处理,类必须将每个事件路由到它的正确处理程序。这一点通过声明一个事件接收映射来实现。
ATL 提供了若干个使此映射更容易的宏:BEGIN_SINK_MAP、END_SINK_MAP 和 SINK_ENTRY。标准格式如下所示:
BEGIN_SINK_MAP(comClass) SINK_ENTRY(id, dispid, func) . . . //additional external event entries END_SINK_MAP()
下面的示例用两个事件处理程序声明一个事件接收映射:
BEGIN_SINK_MAP(CMyObj) SINK_ENTRY(0, Events1, OnClick1) SINK_ENTRY(0, Events2, OnClick2) END_SINK_MAP()
实现已接近完成。最后一步涉及通知和取消通知外部接口。
最后一步是实现一个在适当的时间通知(或取消通知)所有连接点的方法。必须先完成这种通知,外部客户端与对象之间的通信才能发生。在对象变得可见之前,会向对象支持的每个外部调度接口查询输出接口。建立一个连接,并使用对输出接口的引用来处理来自对象的事件。此过程称为“通知”。
在对象使用完外部接口之后,应通知输出接口它们不再由类使用。此过程称为“取消通知”。
由于 COM 对象的独特特性,此过程的具体细节和执行因实现而异。这些细节超出了本主题的范围,不予讨论
【转载出处】http://technet.microsoft.com/zh-cn/office/cc485263(VS.71).aspx
【SINK_ENTRY_INFO】http://technet.microsoft.com/zh-cn/library/2wt7d0s4(v=vs.110).aspx
【ATL COM 对象基础知识】http://technet.microsoft.com/zh-cn/office/cc451370(v=vs.71)