支持 IDispEventImpl
模板类 IDispEventImpl 可用于为 ATL 类中的连接点接收器提供支持。 连接点接收器允许你的类处理从外部 COM 对象触发的事件。 这些连接点接收器使用你的类提供的事件接收器映射进行映射。
若要正确实现类的连接点接收器,必须完成以下步骤:
导入每个外部对象的类型库
声明
IDispEventImpl
接口声明事件接收器映射
建议和取消建议连接点
实现连接点接收器所涉及的步骤都是通过仅修改类的头文件 (.h) 来完成的。
导入类型库
对于你要处理其事件的每个外部对象,你必须导入类型库。 此步骤定义可以处理的事件,并提供声明事件接收器映射时使用的信息。 #import 指令可用于完成此操作。 为你将支持的每个调度接口添加必要的 #import
指令行到你的类的头文件 (.h)。
以下示例导入外部 COM 服务器 (MSCAL.Calendar.7
) 的类型库:
#import "PROGID:MSCAL.Calendar.7" no_namespace, raw_interfaces_only
注意
对于将支持的每个外部类型库必须有一个单独的 #import
语句。
声明 IDispEventImpl 接口
现在你已经导入了每个调度接口的类型库,你需要为每个外部调度接口声明单独的 IDispEventImpl
接口。 通过为每个外部对象添加 IDispEventImpl
接口声明来修改类的声明。 有关参数的详细信息,请参阅 IDispEventImpl。
以下代码为 DCalendarEvents
接口声明了两个连接点接收器,用于由 CMyCompositCtrl2
类实现的 COM 对象:
public IDispEventImpl<IDC_CALENDAR1, CMyCompositCtrl2, &__uuidof(DCalendarEvents), &__uuidof(__MSACAL), 7, 0>,
public IDispEventImpl<IDC_CALENDAR2, CMyCompositCtrl2, &__uuidof(DCalendarEvents), &__uuidof(__MSACAL), 7, 0>
声明事件接收器映射
为了让正确的函数处理事件通知,你的类必须将每个事件路由到其正确的处理程序。 这是通过声明事件接收器映射来实现的。
ATL 提供了多个宏,包括 BEGIN_SINK_MAP、END_SINK_MAP 和 SINK_ENTRY_EX,使此映射更容易。 标准格式如下所示:
BEGIN_SINK_MAP(comClass)
SINK_ENTRY_EX(id, iid, dispid, func)
. . . //additional external event entries
END_SINK_MAP()
以下示例使用两个事件处理程序声明事件接收器映射:
BEGIN_SINK_MAP(CMyCompositCtrl2)
//Make sure the Event Handlers have __stdcall calling convention
SINK_ENTRY_EX(IDC_CALENDAR1, __uuidof(DCalendarEvents), DISPID_CLICK,
&CMyCompositCtrl2::ClickCalendar1)
SINK_ENTRY_EX(IDC_CALENDAR2, __uuidof(DCalendarEvents), DISPID_CLICK,
&CMyCompositCtrl2::ClickCalendar2)
END_SINK_MAP()
实现几乎就要完成了。 最后一步涉及外部接口的建议和取消建议。
建议和取消建议 IDispEventImpl 接口
最后一步是实施一种方法,该方法将在适当的时间建议(或取消建议)所有连接点。 必须先完成此建议,然后才能在外部客户端与对象之间进行通信。 在你的对象变得可见之前,将查询你的对象支持的每个外部调度接口以查找传出接口。 建立连接并使用对传出接口的引用来处理来自对象的事件。 此过程称为“建议”。
使用外部接口完成对象后,应通知传出接口它们不再由你的类使用。 此过程称为“取消建议”。
由于 COM 对象的独特性质,此过程在实现之间因细节和执行而异。 这些详细信息超出了本主题的范围,未进行介绍。