支持 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_MAPEND_SINK_MAPSINK_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 对象的独特性质,此过程在实现之间因细节和执行而异。 这些详细信息超出了本主题的范围,未进行介绍。

另请参阅

ATL COM 对象基础知识