Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций РСОИ.doc
Скачиваний:
20
Добавлен:
04.11.2018
Размер:
1.93 Mб
Скачать

2.11.2. Створення клієнтського застосунка

Щоб клієнтський застосунок реалізував механізм зворотного виклику необхідно виконати певні дії.

1. У визначенні класу форми в секції private передбачити оголошення:

  • для реалізації зворотного викликання.

FCallback:TEventHandler;

TEventHandler – це спеціальний клас, що забезпечує оброблення зворотного виклику; з погляду клієнта методи зворотного виклику є процедурами обробки подій цього класу; з погляду сервера методи зворотного виклику є методами цього класу.

  • для звернення до методів сервера необхідно оголосити змінну:

FServer: IIntfCallback;

Примітка. FServer – вказівник на інтерфейс прямого виклику. Саме цій змінній привласнюється результат виклику методу Create Co-класу CОМ- об’єкту.

  • для збереження результату функції прямого виклику Connect оголошуємо змінну FID.

FID: integer;

Функція Connect буде повертати ідентифікатор клієнта, визначений сервером.

2. Розробити процедуру OnCreateForm, у секції var процедури оголосити змінну

Typelib: ITypelib – вказівник на бібліотеку типів.

У процедурі виконати такі дії:

begin

OleChek (LoadRegTypeLib(LBID_library,1,0,0,Typelib));

FCallback:= TEventHandler.Create(Typelib, IIntfCallbackEvents);

end

Функція LoadRegTypeLib відшукує в реєстрі бібліотеку типів за допомогою функцій системної COM-бібліотеки, повертає у змінну TypeLib вказівник на інтерфейс бібліотеки типів.

Функція OleChek являє собою стандартну оболонку над викликами COM -функцій, параметрами якої є сама COM-функція. Вона забезпечує генерування виключень і їхнє оброблення за замовчуванням, якщо СОМ- функція виконалася невдало.

Як результат, змінній FCallback присвоюється значення, яке повертається конструктором об’єкту типу TEventHandler, воно є вказівником на інтерфейс обробки подій. Конструктору, як параметр, передаються інтерфейс потрібної бібліотеки типів Typelib та ім'я інтерфейсу зворотного виклику цієї бібліотеки типів.

3. Передбачити підключення до сервера

FServer := CoIntfCallback.Create;

FID:= FServer.Connect (FCallback);

4. Реалізувати прямий виклик в клієнтському застосунку за натисканням кнопки Send:

FServer.Sendtext(Edit1.text);

Щоб клієнт відпрацював зворотнє викликання, у ньому необхідно написати процедуру обробки події OnТext для об’єкту класу TEventHandler.

Наприклад:

Procedure TEventHandler.OnТext(Text: WideString);

Begin

Memo1.Lines.Add(Text);

End;

Розглянемо докладніше розроблення клієнтського застосунка. Створіть новий застосунок у середовищі Delphi. У директиву uses головного модуля додайте ім’я файла бібліотеки типів сервера IntfSrv_TLB.pas або імпортуйте бібліотеку типів сервера в Delphi.

Реалізація інтерфейсу зі зворотним викликом

Клієнтський застосунок — це саме той компонент нашого програмного комплексу, у якому має бути реалізований інтерфейс IIntfCallbackEvents, визначений у бібліотеці типів сервера.

Для реалізації методів зворотнього виклику у клієнтському застосунку використовується клас TEventHandler, який є похідним від класу TAutoIntfObject. Клас TAutoIntfObject — це «полегшений» клас підтримки автоматизації, який можна використовувати в тих випадках, коли бажано реалізувати інтерфейс, не «рекламуючи» його в операційній системі Windows. Інакше кажучи, мова йде про інтерфейси, подібні до IIntfCallbackEvents, що є закритими і відомими тільки конкретному серверу і його клієнтам.

Інтерфейс IintfCallbackEvents містить тільки один метод OnText, що реалізований таким чином, що виводить переданий йому текст у головне вікно застосунка. Отже, клієнтський застосунок має містити наступне оголошення методу зворотнього виклику:

type

TEventHandler = class(TAutoIntfObject, IIntfCallbackEvents)

procedure OnText(const Text: WideString); safecall;

end;

Формування об’єкту зі зворотним викликом

При запуску клієнтський застосунок створює об’єкт класу TEventHandler. У такому випадку для створення класу клієнтська програма викликає функцію LoadRegTypeLib, передаючи їй GUID і номер версії бібліотеки типів. Функція LoadRegTypeLib повертає посилання на інтерфейс ITypeLib. Метод TEventHandler.Create використовує це посилання для формування екземпляра FCallback класу TEventHandler, який буде переданий серверу для здійснення зворотнього викликання. Відповідний текст виглядає так:

procedure TForm1.FormCreate(Sender: Tobject);

var TypeLib : ITypeLib;

begin

OleCheck(LoadRegTypeLib(LIBID_IntfSrv, 1, 0, 0, TypeLib));

FCallback:=TEventHandler.Create(TypeLib, IIntfCallbackEvents};

end;

Підключення до сервера

У процедурі обробки події OnClick кнопки Connect викликається метод CoIntfCallback.Create для створення екземпляра сервера. Потім відбувається викликання методу прямого виклику Connect інтерфейсу IIntfCallback СОМ-об’єкту з передаванням посилання на інтерфейс зворотного виклику IIntfCallbackEvents, реалізований у класі TEventHandler на стороні клієнта. У коді програми передається сам об’єкт TeventHandler, a Delphi автоматично перетворить його в інтерфейс IIntfCallbackEvents.

За подією OnClick кнопки SendText, викликається метод прямого виклику SendText, реалізація якого на сервері містить виклик методу зворотного виклику OnText для всіх підключених у цей момент клієнтів.

Програмний код цього клієнтського застосунка наведений у лістингу:

unit MainForm;

interface

uses

Windows, . . .,ComObj, ActiveX, IntfSrv_TLB;

type

TEventHandler = class(TAutoIntfObject, IIntfCallbackEvents)

TForm1 = class(TForm);

Panel1: TPanel; Panel2: TPanel;

btnSend: TButton;

Memo1: TMemo; Edit1: TEdit;

btnConnect: TButton;

btnDisconnect: TButton;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure btnConnectClick(Sender: TObject);

procedure btnDisconnectClick(Sender: TObject);

procedure btnSendClick(Sender: TObject);

private

{ Оголошення закритих членів}

FCallback: TEventHandler;

FServer: IIntfCallback;

FID: Integer;

public

{ Оголошення загальнодоступних членів }

end;

var Form1: TForm1;

implementation

{SR *.DFM}

{ TEventHandler }

procedure TEventHandler.OnText(const Text: WideStrinq);

begin

Form1.Memo1.Lines.Add(Text);

end;

procedure TForm1.FormCreate{Sender: TObject);

var TypeLib : ITypeLib;

begin

//Для доступу до інтерфейсу події використовуємо LoadRegTypeLib

OleCheck(LoadRegTypeLib(LIBID_IntfSrv, 1, 0, 0,TypeLib));

FCallback:=TEventHandler.Create(TypeLib, IIntfCallbackEvents);

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

// He потрібно тут видаляти FCallback – це зробить сервер

end;

procedure TForm1.btnConnectClick(Sender: TObject);

begin

// Підключення до сервера

FServer := CoIntfCallback.Create;

FID := FServer.Connect(FCallback);

btnConnect.Enabled := False;

btnDisconnect.Enabled:= True;

btnSend.Enabled := True;

Edit1.Enabled := True;

end;

procedure TForm1.btnDisconnectClick(Sender: TObject);

begin

FServer.Disconnect(FID);

btnConnect.Enabled := True;

btnDisconnect.Enabled := False;

btnSend.Enabled := False;

Edit1.Enabled := False;

end;

procedure TForm1.btnSendClick(Sender: TObject);

begin

FServer.SendText(Edit1.Text) ;

end;

end.

Виконавши вищезазначені дії, можна організувати зворотний виклик за допомогою звичайних інтерфейсів. На рис. 2.9 зображено зовнішній вигляд екранної форми розробленого клієнтського застосунка.

Контрольні запитання та завдання:

  1. Наведіть основні принципи обробки подій в серверах автоматизації.

  2. Наведіть принципи оброблення подій в серверах автоматизації на основі інтерфейсів диспетчерування.

  3. Наведіть принципи оброблення подій в серверах автоматизації на основі звичайних інтерфейсів автоматизації.

  4. Як проводиться створення сервера автоматизації з підтримкою подій на основі інтерфейсів диспетчерування?

  5. Як проводиться створення сервера автоматизації з підтримкою подій на основі звичайних інтерфейсів автоматизації?

  6. Опишіть призначення класу TEventHandler та особливості його використання.

  7. Опишіть призначення класу TAutoIntfObject та особливості його використання.

  8. Як проводиться підключення множини клієнтів до сервера?