Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Подземелье Магов
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  08:59[Войти] | [Зарегистрироваться]

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

Андрей Семак
дата публикации 22-05-2001 00:00

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

Введение

Обработка событий является одним из ключевых моментов в 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
    procedure ReportLog(enMsgType: LogMessageTypes; const strUserName,
      strModuleName, strMsgText: WideString); safecall;
    { Protected declarations }
  end;
Библиотека типов изображена на рис. 1.

В разделе 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 изображено на рис.2.

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

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

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

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

  ComObj, ActiveX, SystemLogger_TLB, StdVcl, LogEvent_TLB, Dialogs;
type

  TSysLog = class(TAutoObject, ISysLog, ISysLogEvent)
  protected
    procedure ReportLog(enMsgType: LogMessageTypes; const strUserName,
      strModuleName, strMsgText: WideString); safecall;
    { Protected declarations }

  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. Как это сделать? Смотрите рис. 4.


Рис. 4

Далее следуйте инструкциям визарда и сделайте выбор как показано на рис.5


Рис. 5

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

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

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

  ComObj, ActiveX, BsObject_TLB, StdVcl, LogEvent_TLB;

type

  TBusinessObject = class(TAutoObject, IBusinessObject)
  protected
    function NewObject(param1: Integer): HResult; safecall;
    { Protected declarations }
  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.

Скачать пример Com_Events_Example.Zip (21 K)

Андрей Семак
Компания ProFIX
май 2001г.




Смотрите также материалы по темам:
[TObject] [TList] [TTimer] [COM-объекты]

 Обсуждение материала [ 26-04-2009 07:01 ] 3 сообщения
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования