Функция InOutData устанавливает параметры запроса и
выполняет его, после чего вызывает функцию CollectInOutData, которая выполняет
основную работу.
На этом этапе сервер приложений полностью закончен, и
можно, запустив его один раз для регистрации в реестре как СОМ-сервера, приступать к созданию клиентской части.
Клиент
Задача клиентского приложения – взаимодействовать с
пользователем и отображать нужную ему информацию.
Интерфейс клиента может быть каким угодно, поэтому
остановлюсь только на особенностях работы с данным сервером приложений.
В прилагаемых исходных текстах имеется клиентское
приложение, содержащее три модуля данных (TdataModule), dmCommon, dmDoc и
dmReport. Каждый из них предназначен для соединения с соответствующим удаленным
модулем данных.
Я не буду здесь останавливаться подробно на описаниях
реализации клиентской части, но некоторые особенности необходимо рассмотреть.
Для использования сервера приложений его библиотека
типов импортирована в клиентское приложение.
ПРИМЕЧАНИЕ
Дело в том, что для соединения
клиентского приложения с сервером в данном случае используется
TSocketConnection (scDoc). При обращении к интерфейсу удаленного модуля как к
variant (через свойство AppServer) вызовы методов сервера в некоторых случаях
вызывают сбой (Access violation). Поэтому все вызовы я произвожу через
dispinterface, имя которого отличается от имени исходного интерфейса
суффиксом Disp. Импорт библиотеки типов как раз и позволяет обращаться к
этому интерфейсу.
Кроме того, при обращении к серверу с
импортированной библиотекой типов все параметры процедур проверяются на этапе
компиляции, и вызов GetDispIDsOfNames не производится, что ускоряет вызовы
методов.
Для импорта надо выбрать пункты меню Project ->
Import Type Library, и выбрать в списке DocServer library. Не забудьте, что сервер при этом должен быть зарегистрирован в
реестре. После этого остается отключить опцию Generate Component Wrapper и
нажать Create Unit, поскольку компонент в данном случае не нужен, достаточно
только объявлений.
|
Работа с поставщиками и получателями
Свойство DMCommon.ClientName обеспечивает обращение к
методу сервера:
property
ClientName[ID: integer]: string read GetClientName;
function
TDMCommon.GetClientName(ID: integer): string;
var
AServer: IrdmCommonDisp;
begin
Result := '';
if ID = 0 then Exit;
AServer :=
IrdmCommonDisp(scCommon.GetServer);
Result := AServer.ClientName[ID];
AServer := nil;
end;
|
Компонент scCommon: TSocketConnection после соединения
с сервером приложений выдает в качестве результата метода GetServer ссылку на
интерфейс удаленного модуля данных, остается просто преобразовать ее к нужному
типу.
Получение нового идентификатора для поставщика и
получателя производится в обработчике события OnNewRecord:
procedure
TDMCommon.cdsClientNewRecord(DataSet: TDataSet);
var
AServer: IrdmCommonDisp;
begin
AServer :=
IrdmCommonDisp(scCommon.GetServer);
cdsClient.FieldByName('CLIENT_ID').AsInteger
:= AServer.NewClientID;
AServer
:= nil;
end;
|
Работа с документами
Удаление документа происходит прямо из списка. Это
делается в обработчике события компонента TAction. А вот редактирование и
добавление нового документа производится в отдельном модуле DMDoc, привязанном
к rdmDoc: