Основы COM. Рудалев В.Г - 33 стр.

UptoLike

33
При возникновении события в COM-сервере , которое он должен передать кли -
енту , сервер должен вызвать какой -либо из методов клиента . Фактически в этот
момент клиент с сервером меняются местами . Обращение к клиенту осуществ -
ляется при помощи стандартных механизмов COM. Основная идея заключается
в том, что сервер, генерирующий события, декларирует интерфейс их обработ-
чика . Клиент, подписывающийся на события, должен реализовать этот интер-
фейс (то есть фактически должен включать в себя COM-объект, реализующий
интерфейс). Кроме того, сервер должен реализовать стандартные интерфейсы
COM, позволяющие зарегистрировать на нем обработчик событий. Используя
эти интерфейсы , клиент регистрирует на сервере интерфейс обработчика собы -
тий, позволяя серверу вызывать свои методы. Рассмотрим основные интерфей -
сы , используемые в этом процессе.
Каждый COM-объект, который позволяет подключаться к своим событиям ,
реализует интерфейс IConnectionPointContainer:
type
IConnectionPointContainer = interface
['{B196B284-BAB4-101A-B69C-00AA00341D07}']
function EnumConnectionPoints(out Enum: IenumConnec-
tionPoints): HResult;stdcall;
function FindConnectionPoint(const iid: TIID;
out cp: IConnectionPoint): HResult; stdcall;
end;
Объект, нуждающийся в оповещении о событиях (клиент), должен запросить у
источника этот интерфейс (называемый исходящим интерфейсом), затем при
помощи метода FindConnectionPoint получить «точку подключения»
интерфейс IConnectionPoint и посредством вызова его метода Advise за-
регистрировать в этой точке подключения ссылку на свою реализацию интер-
фейса IDispatch, методы которого будут вызываться при возникновении тех
или иных событий в источнике событий. Основной метод
FindConnectionPoint получает GUID интерфейса - обработчика и возвра -
щает указатель на соответствующую этому обработчику «точку подключения» .
В случае успеха метод возвращает S_OK, в случае неудачи код ошибки .
Точка подключения также представляет собой интерфейс IConnection-
Point. Основные методы этого интерфейса Advise и UnAdvise. Пер-
вый метод регистрирует на сервере клиентский интерфейс обработчика собы -
тий, который передается в параметре unkSink. Метод возвращает dwCookie
идентификатор подключения, который должен использоваться при отключе -
нии обработчика событий. Начиная с этого момента , сервер при возникновении
события вызывает методы переданного ему интерфейса - обработчика . Метод
Unadvise отключает обработчик от сервера .
Delphi существенно упрощает работу , автоматизируя операции с перечислен-
ными интерфейсами . Рассмотрим следующий пример. Создадим простой COM-
сервер, который при изменении текста в своем окне (со стороны пользователя
                                            33
При в оз ни кнов ени и собы ти я в COM-серв ере, которое он д олж ен перед ать кли -
енту, серв ерд олж ен в ы з в ать какой -ли бо и з метод ов кли ента. Ф акти чески в этот
момент кли ентссервером меняю тся местами . О бращ ени еккли енту осущ еств -
ляетсяпри помощ и станд артны х механи з мов COM. О снов наяи д еяз аклю чается
в том, что сервер, генери рую щ и й собы ти я, д еклари руети нтерфей си х обработ-
чи ка. К ли ент, под пи сы в аю щ и й ся на собы ти я, д олж ен реали з ов ать этот и нтер-
фей с (то есть факти чески д олж ен в клю чать в себя COM-объект, реали з ую щ и й
и нтерфей с). К роме того, серверд олж ен реали з ов ать станд артны е и нтерфей сы
COM, поз в оляю щ и е з ареги стри ров ать на нем обработчи ксобы ти й . И спольз уя
эти и нтерфей сы , кли ентреги стри руетна сервереи нтерфей собработчи ка собы -
ти й , поз в оляя серверу в ы з ы в ать св ои метод ы . Рассмотри м основ ны еи нтерфей -
сы , и спольз уемы ев этом процессе.
К аж д ы й COM-объект, которы й поз в оляет под клю чаться к св ои м собы ти ям,
реали з уети нтерфей сIConnectionPointContainer:
type
   IConnectionPointContainer = interface
       ['{B196B284-BAB4-101A-B69C-00AA00341D07}']
       function EnumConnectionPoints(out Enum: IenumConnec-
                                 tionPoints): HResult;stdcall;
       function FindConnectionPoint(const iid: TIID;
              out cp: IConnectionPoint): HResult; stdcall;
   end;
О бъект, нуж д аю щ и й ся в опов ещ ени и о собы ти ях (кли ент), д олж ен з апроси ть у
и сточни ка этот и нтерфей с (наз ы в аемы й и сходящи м и нте рф е йсом), з атем при
помощ и метод а FindConnectionPoint получи ть «точку под клю чени я» –
и нтерфей сIConnectionPoint и посред ств ом в ы з ов а его метод а Advise з а-
реги стри ров ать в этой точке под клю чени я ссы лку на св ою реали з аци ю и нтер-
фей са IDispatch, метод ы которого буд утв ы з ы в аться при в оз ни кнов ени и тех
и ли    и ны х    собы ти й     в     и сточни ке собы ти й .      О снов ной     метод
FindConnectionPoint получает GUID и нтерфей са-обработчи ка и в оз в ра-
щ аетуказ атель на соотв етств ую щ ую этому обработчи ку «точку под клю чени я» .
В случаеуспеха метод в оз в ращ аетS_OK, в случаенеуд ачи — код ош и бки .
Т очка под клю чени я такж е пред став ляет собой и нтерфей с IConnection-
Point. О снов ны еметод ы этого и нтерфей са — Advise и UnAdvise. Пер-
в ы й метод реги стри рует на сервере кли ентски й и нтерфей с обработчи ка собы -
ти й , которы й перед ается в параметре unkSink. М етод в оз в ращ ает dwCookie
— и д енти фи каторпод клю чени я, которы й д олж ен и спольз ов атьсяпри отклю че-
ни и обработчи ка собы ти й . Н ачи наясэтого момента, серверпри в оз ни кнов ени и
собы ти я в ы з ы в ает метод ы перед анного ему и нтерфей са-обработчи ка. М етод
Unadvise отклю чаетобработчи котсервера.
Delphi сущ еств енно упрощ ает работу, ав томати з и руя операци и с перечи слен-
ны ми и нтерфей сами . Рассмотри м след ую щ и й при мер. Соз д ад и м простой COM-
серв ер, которы й при и з менени и текста в св оем окне (со стороны польз ов ателя