На этом шаге мы рассмотрим алгоритм добавления событий .
Теперь перейдем к реализации событий 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 Кб).
На следующем шаге мы рассмотрим добавление метода.