Поддержка 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
com-объекта, реализованного по классу CMyCompositCtrl2
:
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-объектов эта процедура зависит от детализации и выполнения между реализациями. Эти сведения выходят за рамки этой статьи и не рассматриваются.