Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

Видеокурс программиста и крэкера 5D 2O17
(актуальность: октябрь 2O17)
Свежие инструменты, новые видеоуроки!

  • 400+ видеоуроков
  • 800 инструментов
  • 100+ свежих книг и статей

УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

БОЛЬШОЙ FAQ ПО DELPHI



Реализация событий COM+ в среде Delphi

Введение

Обработка событий является одним из ключевых моментов в COM. Существует масса программ, для нормального функционирования которых требуется поддержка событий.

GUI пользователя должен уметь обрабатывать различное количество событий, например, таких как: нажатие на кнопку мыши, перемещение мыши по экрану и т.д. Приблизительно так же может возникнуть потребность обрабатывать события внутри объектов COM. В данной статье мы рассмотрим принцип работы свободно связанных событий и создадим наглядное приложение для демонстрации использования такого типа событий в COM+. (Для более детальной информации о события в COM+ смотрите статью А.Новика «Система поддержки событий COM+» на сайте журнала «Клиент-Сервер»).

Что такое свободно связанные события? Понятие «Издатель-Подписчик»

До появления COM+, модель COM поддерживала систему событий, реализованную через интерфейс IConnectionPointContainer. Это жестко связанные события. (В данной статье, мы не будем рассматривать реализацию этого подхода). В COM+ появилось новое понятие: СВОБОДНО СВЯЗАННЫЕ СОБЫТИЯ (Loosely coupled events - LCE), разработанные для удовлетворения потребностей распределенных вычислений.

В COM+ Инициатор события (Издатель) и потребитель (Подписчик) свободно связаны.

Информация от различных издателей хранится в каталоге COM+, а подписчики указывают, какую информацию они хотят получать, регистрируясь в каталоге.

Архитектура событий в COM+

Для реализации свободно связанных событий вы должны создать компонент EventClass, который будет зарегистрирован в каталоге COM+. Подписчики вызываются объектом события, который определяет и активизирует объекты, подписанные на него.

Следует различать виды подписки. Существует временная и постоянная подписки:

Временная подписка (transient)
создается средствами административного API. Для более детальной информации можно обратиться в MSDN. Управлять жизненным циклом такой подписки нужно программными средствами. А не средствами ComponentServices.
Постоянная подписка (persistent)
создается средствами ComponentServices. Такая подписка в состоянии пережить перезапуск системы.

Фильтрация существует только в системе COM+. Такой возможности нет в системе жестко связанных событий. Её суть мы рассмотрим дальше, при более детальном изучении примера.

Пример реализации компонента EventClass

Допустим, у нас существует задача на базе существующей системы, функционирующей в среде COM+, реализовать систему ведения собственно журнала событий в текстовом файле. Для начала нам нужно реализовать компонент EventClass, о котором речь шла выше. Он будет представлять собой пустую заглушку для подписчика. Именно через него будут запускаться наши подписчики в каталоге COM+.

Когда компонент-издатель будет создавать событие, компонент EventClass передаст все входящие параметры события и активизирует всех подписчиков.

Важно! Метод события может содержать только входные параметры [in]. Выходным может быть только результирующий тип HRESULT, принятый в COM для определения статуса завершения S_OK, в результате удачи или E_FAIL, в результате неудачи выполнения метода.

Запустим среду Delphi, создадим простую ActiveX библиотеку и поместим в неё объект автоматизации (Automation Object). Определим нумератор типов ошибок и создадим интерфейс ISysLogEvent с методом ReportLog.


 type
 
 LogMessageTypes = TOleEnum;
 
 const
   lmtInformation = $00000000;
   lmtWarning = $00000001;
   lmtError = $00000002;
   lmtFatal = $00000003;
   lmtDebug = $00000004;
   lmtUnknown = $00000005;
 
 type
   TSysLogEvent = class(TAutoObject, ISysLogEvent)
   protected
   { Protected declarations }
     procedure ReportLog(enMsgType: LogMessageTypes; const strUserName,
       strModuleName, strMsgText: WideString); safecall;
 end;
 

В разделе Implementation создадим заглушку метода для EventClass:


 implementation
 
 uses
   ComServ;
 
 procedure TSysLogEvent.ReportLog(enMsgType: LogMessageTypes;
   const strUserName, strModuleName, strMsgText: WideString);
 begin
 
 // Event class methods are not implemented.
 
 end;
 
 initialization
 
 TAutoObjectFactory.Create(ComServer, TSysLogEvent, Class_SysLogEvent,
   ciMultiInstance, tmApartment);
 
 end.
 

На этом закончим. Остается зарегистрировать заглушку в нашем приложении COM+. Если приложение не создано, создайте его через средства ComponentServices.

Пример реализации Объекта-подписчика

После регистрации компонента EventClass создадим компонент-подписчик:

  1. Точно так же, как при создании компонента EventClass создадим библиотеку и объект автоматизации. Немного будет отличаться наполнение реализации методов и метод регистрации.
  2. Создадим интерфейс с методом, аналогичным методу интерфейса ILogEvent – ISysLog

Важно! Не забудьте подключить в вашу библиотеку типов зарегистрированную в ComponentServices библиотеку с заглушкой EventClass и укажите интерфейс ISysLogEvent в разделе Implements.

Ниже приведен код компоненты подписчика, который будет получать события от издателя. Из реализации бизнес-логики видно, что при возникновении метода-события ReportLog, компонент-подписчик будет выдавать диалоговое окно с информацией для записи в журнал. Если вы замените реализацию этого метода программным кодом записи в файл, вы получите готовый компонент для регистрации ваших событий в бизнес объекте (вывода информации, сообщений об ошибках, отладке и т.д.).


 unit SysLogUnit;
 
 interface
 
 uses
   ComObj, ActiveX, SystemLogger_TLB, StdVcl, LogEvent_TLB, Dialogs;
 
 type
   TSysLog = class(TAutoObject, ISysLog, ISysLogEvent)
   protected
     { Protected declarations }
     procedure ReportLog(enMsgType: LogMessageTypes; const strUserName,
       strModuleName, strMsgText: WideString); safecall;
 end;
 
 implementation
 
 uses
   ComServ, SysUtils;
 
 procedure TSysLog.ReportLog(enMsgType: LogMessageTypes; const strUserName,
   strModuleName, strMsgText: WideString);
 begin
   ShowMessage('MessageType : '+IntToStr(enMsgtype)+#10#13+
   'ModuleName : '+strModuleName+#10#13+
   'UserName : '+strUserName+#10#13+
   'TextMessage : '+strMsgText);
 end;
 
 initialization
   TAutoObjectFactory.Create(ComServer, TSysLog, Class_SysLog,
     ciMultiInstance, tmApartment);
 end.
 

Зарегистрируйте компонент в каталоге COM+ и подпишите его к компоненту EventClass.

Далее следуйте инструкциям визарда.

Итак, у вас на компьютере установлены объекты EventClass и подписчик.

Пример реализации методов издателя

Создадим простенькое приложение и проверим существующею связку. Создайте бизнес-объект COM+ инициирующий в любом своем методе метод-событие ReportLog.

Пример реализации объекта приведен ниже:


 unit BsObjectUnit;
 
 interface
 
 uses
   ComObj, ActiveX, BsObject_TLB, StdVcl, LogEvent_TLB;
 
 type
   TBusinessObject = class(TAutoObject, IBusinessObject)
   protected
     { Protected declarations }
     function NewObject(param1: Integer): HResult; safecall;
 end;
 
 implementation
 
 uses
   ComServ;
 
 function TBusinessObject.NewObject(param1: Integer): HResult;
 var
   LogEvent: ISysLogEvent;
 begin
   LogEvent := CoSysLogEvent.Create;
   try
     LogEvent.ReportLog(lmtInformation, 'Nonamed', 'BsObjectUnit',
       'TBusinessObject.NewObject executed!')
   except
     LogEvent.ReportLog(lmtInformation, 'Nonamed', 'BsObjectUnit',
       'TBusinessObject.NewObject failed!')
   end;
 end;
 
 initialization
 TAutoObjectFactory.Create(ComServer, TBusinessObject,
   Class_BusinessObject, ciMultiInstance, tmApartment);
 
 end.
 

После вызова метода NewObject у объекта BusinessObject будет создано событие, которое создаст объект SysLog и запишет и отобразит информацию в диалоговом окне. Подписчиков у созданного объекта EventClass может быть неограниченное количество с самыми разнообразными функциями, от отображения диалогового окна до записи данных в отдельную БД.

Фильтры

Механизм фильтрации подписчиков использует строку условия фильтрации, являющуюся свойством подписки. Такая фильтрация выполняется для каждого метода и каждой подписки. Вы можете использовать строку, используя имена параметров из библиотеки типов. Можно использовать так же стандартные операции отношения, вложенные скобки и ключевые слова AND, OR, NOT. Строка может быть определена с помощью средств ComponentServices или средств административного API.




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS