На этом шаге мы рассмотрим алгоритм добавления событий .
Теперь перейдем к реализации событий Click и Jackpot в элементе управления. Чтобы понять, как реализуются СОМ-события, откройте IDL-файл проекта (OneArmedBanditATL.idl) и просмотрите определение библиотеки типов. Оно приведено ниже.
[
uuid(101D4AD7-1664-4B7D-892C-F80F09DF6736),
version(1.0),
helpstring("OneArmedBanditATL 1.0 Type Library")
]
library ONEARMEDBANDITATLLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(DBCF419B-E964-46DF-A213-61B77437A14E),
helpstring("_IATLBanditEvents Interface")
]
dispinterface _IATLBanditEvents
{
properties:
methods:
};
[
uuid(C2EC69E2-0750-413E-AD83-BB8EB3DB9A27),
helpstring("ATLBandit Class")
]
coclass ATLBandit
{
[default] interface IATLBandit;
[default, source] dispinterface _IATLBanditEvents;
};
};
В определении библиотеки типов ONEARMEDBANDITATLLIB имеется определение диспетчерского интерфейса _IATLBanditEvents. Этот интерфейс объявлен внутри блока сокласса ATLBandit, что свидетельствует о том, что элемент управления ATLBandit предоставляет интерфейс _IATLBanditEvents. Обратите, однако, внимание, что этот интерфейс объявлен с IDL-атрибутом [source], указывающим, что _IATLBanditEvents работает в качестве источника событий. Этот вид интерфейса известен как точка стыковки (connection point). COM-объекты, предоставляющие точки стыковки, реализуют интерфейс IConnectionPointContainer, управляющий подключением интерфейсов источников событий к соответствующему объекту-клиенту - приемнику (sink). Приемник реализует методы, определяемые объектом-источником. Механизм точек стыковки позволяет передавать источнику указатель на интерфейс приемника, таким образом предоставляя источнику доступ к методам приемника. Для генерации события источник вызывает соответствующий метод интерфейса приемника.
Первый этап определения события - создание представляющего его метода в интерфейсе источника.

Рис.1. Добавление метода Click

Рис.2. Мастер Implement Connection Point Wizard
Мастер создает класс-представитель (proxy class) - не путайте с представителем в маршалинге, - который содержит функции-представители (proxy functions), реализующие методы события нашего интерфейса событий. Если Вы обратитесь к ClassView, то увидите, что проекте появился класс CProxy_IATLBanditEvents, предоставляющий генерирующие события функции Fire_Click() и Fire_Jackpot(). ATL модифицирует определение CATLBandit так, чтобы он был производным класса CProxy_IATLBanditEvents, делая методы Fire_Click() и Fire_Jackpot() доступными в качестве членов класса Вашего элемента управления.
Кроме того, мастер Implement Connection Point Wizard создает в классе следующую карту точек стыковки (файл ATLBandit.h):
BEGIN_CONNECTION_POINT_MAP(CATLBandit) CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink) CONNECTION_POINT_ENTRY(DIID__IATLBanditEvents) END_CONNECTION_POINT_MAP()
Убедитесь, что карта точек стыковки выглядит именно так, как показано выше, - в некоторых случаях ATL не может корректно сформировать ее, что приводит к ошибкам при компиляции.
Теперь Вы можете использовать функции-представители для генерации событий в Вашем элементе управления. Для демонстрации этого напишем тело функции-обработчика, которая генерирует событие Click при щелчке мышью в области элемента управления.

Рис.3. Добавление функции-обработчика
Fire_Click();

Рис.4. Добавление вызова функции Fire_Click()
Текст приложения можно взять здесь (33,9 Кб).
На следующем шаге мы рассмотрим добавление метода.