Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методическое пособие по СПр.doc
Скачиваний:
7
Добавлен:
16.12.2018
Размер:
690.69 Кб
Скачать

Компонент tddeServerConv

В этом компоненте самую важную роль играет единственное свойство - Name. Имя компонента совпадает с именем темы, которую он поддерживает. Клиент должен знать это имя при установлении контакта, за исключением того случая, когда он подключается к данным контакта, которые скопированы в буфер обмена (такую возможность реализует компонент TDDEServerItem).

В моменты открытия и закрытия контакта возникают события:

property OnOpen: TNotifyEvent;

property OnClose: TNotifyEvent;

Первоначально протокол DDE был ориентирован только на оперативное получение данных клиентом от сервера, но позже его возможности расширились. Клиент может передать для выполнения серверу набор макрокоманд — для этого у него есть нужные методы. На стороне сервера за их исполнение отвечает обработчик события:

TMacroEvent=procedure(Sender:TObject; Msg:TStrings) of object; property OnExecuteMacro: TMacroEvent;

Если вы хотите, чтобы ваш сервер DDE мог исполнять макрокоманды, подаваемые с клиента, то нужно предусмотреть такой обработчик. Передаваемые команды содержатся в параметре Msg в виде набора строк. Можно вызвать процесс выполнения команд и из приложения-сервера, с помощью метода

function ExecuteMacro(Data: HDDEData): Longlnt;

В этом случае параметр Data должен содержать дескриптор строки с командами (типа pChar).

Компонент tddeServerItem

Этот компонент реализует элемент данных, которые при установленном контакте будут передаваться клиенту. В принципе, протокол DDE подразумевает обмен любыми данными, формат которых зарегистрирован в системе для передачи через буфер обмена. Но для рассматриваемых компонентов Delphi эти возможности ограничиваются только текстовыми данными. Так что свойство, содержащее формат обмена данными:

property Emt: Integer;

всегда равно cf_text.

Данные содержатся в свойствах:

property Text: string; property Lines: TStrings;

По сути дела, первое свойство представляет собой подмножество второго. При чтении значение свойства Text соответствует первой строке Lines. Но если вы присваиваете ему значение, все прочие строки Lines очищаются.

Элемент данных должен быть связан с определенной темой. В свойстве:

property ServerConv: TDDEServerConv;

procedure CopyToClipboard;

Для вступления в контакт посредством буфера обмена клиент может вызвать метод GetPasteLinkInfo (см. ниже), и, проанализировав имена сервера, темы и элемента, принять решение о вступлении.

Клиент может переустановить данные сервера. При переустановке возникает событие:

property OnPokeData: TNotifyEvent;

Кроме того, может быть использован метод:

function PokeData(Data: HDDEData): LongInt;

Параметр Data должен представлять собой дескриптор области памяти, в которой содержится текстовая строка типа pChar.

В отличие от OnPokeData, событие:

property OnChange: TNotifyEvent;

возникает при любом изменении данных, например, присвоении значений свойствам Text или Lines или при вызове PokeData. Оно может также быть вызвано явно из метода:

procedure Change;

Компонент TDDEClientConv

Компонент TDDEClientConv осуществляет контакт на клиентской стороне. Именно в нем описаны методы, отвечающие за установление контакта.

Имена требуемых сервера DDE и темы содержатся в свойствах:

property DDEService: String;

property DDETopic: String;

Сервер и тема устанавливаются при вхождении в контакт. Предусмотрены два режима вхождения в него:

property ConnectMode: TDataMode; TDataMode = (DDEAutomatic,

DDEManual);

Метод function SetLink(const Service:string; const Topic:string): Boolean; присваивает свойствам "сервер" и "тема" значения, равные значению параметров Service и Topic, а если выбран режим контакта ddeAutomatic — то и устанавливает контакт. Будьте внимательны при задании параметров метода — в этих строках учитывается регистр символов.

В режиме ddeManual для установления контакта необходимо вызвать дополнительно метод:

function OpenLink: Boolean;

Этот метод сначала закрывает предыдущий контакт, затем он пытается связаться с сервером DDEService на тему DDETopic. Если это не удается сразу (например, если требуемый сервер DDE отсутствует), то предпринимается попытка загрузить программу с именем, определенным в свойстве:

property ServiceApplication: String;

и установить контакт с ней. Если оно не определено (ServiceApplication=''), то в качестве последней попытки для контакта пробуется имя, представляющее собой конкатенацию имен сервера и темы, разделенных пробелом. В случае неудачи метод OpenLink возвращает значение False.

Можно связаться с сервером, если он поместил данные о контакте в буфер обмена. В этом случае метод:

function PasteLink: Boolean;

переключит компонент на новый контакт и вернет значение True.

Наконец, метод:

procedure CloseLink;

разрывает контакт с сервером DDE.

Метод function StartAdvise: Boolean; инициирует начало обмена данными. Обычно он вызывается в методе OpenLink.

Как уже упоминалось, основное направление потоков данных — от сервера к клиенту, однако возможно и обратное. При помощи двух методов можно присвоить новые значения элементу данных сервера:

function PokeDataLines(const Item:string; Data:TStrings): Boolean;

function PokeData(const Item: string; Data: PChar): Boolean;

Здесь параметр Item — имя элемента данных, Data — передаваемые текстовые данные.

Кроме того, некоторые серверы DDE имеют собственные наборы макрокоманд, запрос на выполнение которых можно послать от клиента. К ним относятся многие приложения, в т.ч. такие, как Paradox и MS Excel, а также Explorer. Запрос на выполнение макрокоманд посылают методы:

function ExecuteMacroLines(Cmd:TStrings; waitFlg: Boolean): Boolean;

function ExecuteMacro(Cmd: PChar; waitFlg: Boolean): Boolean;

Серверу может потребоваться определенное время для выполнения этих операций. Если до их окончания снова загрузить его работой, это может привести к непредсказуемым результатам. Чтобы отследить состояние сервера, нужно установить параметр функции waitFlg в True. С началом операции свойство property WaitStat: Boolean; устанавливается в True. При этом вызовы последних четырех методов отрабатываться не будут, пока сервер не известит об окончании операции, и свойство WaitStat не примет значение False. Это свойство доступно только для чтения.

В качестве примера рассмотрим управление при помощи макрокоманд таким приложением, как MS Word. В примере динамически создается компонент TDDEClientConv, которому на исполнение передаются макрокоманды:

macros:array[0..1023] of char;

begin

with TDDECIientConv.Create(Self) do

begin

ServiceApplication:='WinWord';

if (SetLink('Winword','System')) then

begin

OpenLink;

StrPCopy(macros,'[InsertFile.Name="c:\autoexec.bat"]');

ExecuteMacro(macros,FALSE);

StrPCopy(macros,'[InsertPicture.Name = "c:\Windows\win.bmp"]');

ExecuteMacro(macros,FALSE);

CloseLink;

end

else

ShowMessage('MS Word not found!'); Free;

end;

end;

По вашему требованию в текущий документ Word будут вставлены текст файла autoexec.bat и картинка. Примененные здесь InsertFile и InsertPicture — лишь немногие из макросов, поддерживаемых приложениями из состава Microsoft Office. Подробную информацию можно получить в документации для разработчика пакета Office.

Примечание. Существуют и другие, более эффективные средства управления Office, чем описанный, в частности — через автоматизацию СОМ.

Клиент может запросить данные от сервера немедленно с помощью метода:

function RequestData(const Item: string): PChar;

Формат обмена данными можно узнать при помощи свойства:

property DDEFmt: Integer;

Если возможностей, предоставляемых методами и свойствами класса, недостаточно, то для вызова процедур библиотеки DDEML программисту доступен дескриптор контакта:

property Conv: HConv;

В полученном от сервера тексте могут быть специальные управляющие символы — <Enter>, <Tab>, <Backspace> и другие. Их можно отфильтровать (подавить), если свойство:

property FormatChars: Boolean;

установлено в значение False. В этом случае все символы ASCII с десятичными кодами от 1 до 31 заменяются на пробел (код 32). Если свойство равно True, преобразования не происходит.

Так же, как и в TDDEServerConv, при открытии и закрытии контакта вы можете выполнить специфические действия путем обработки событий:

property OnOpen: TNotifyEvent;

property OnClose: TNotifyEvent;