В очередной своей работе я хочу рассказать о DDE - Dynamic Data Exchange, то есть о динамическом обмене данными между приложениями. Начав изучать тему DDE, я понял, что это как-то похоже на чат. Принцип работы с DDE - это технология Клиент-Сервер. Delphi позволяет создавать как сервер, так и клиент. Все компоненты для организации технологии DDE находятся на странице System Палитры компонентов. Сразу хочу отметить, что при использовании DDE возникает множество проблем, которые будут оговорены далее.
Компонент TDdeServerConv представляет собой сеанс передачи данных, а компонент TDdeServerItem
- сами передаваемые данные. Обычно приложение Сервера содержит один компонент TDdeServerConv и
несколько компонентов TDdeServerItem. Эти компоненты используются совместно. Через свойство
ServerConv компонент TDdeServerItem связывается с TDdeServerConv.
Так как TDdeServerItem содержит сами передаваемые данные, то эти данные должны где-то содержаться. Все данные заносятся в два основных свойства: Lines - для передачи сразу нескольких строк и Text - для передачи одной строки. Как только одно из этих свойств изменяться, они сразу же передаются приложению Клиента.
Для того чтобы организовать соединение Клиента с Сервером, Клиенту нужно знать все параметры Сервера.
Для этого нужно использовать метод CopyToClipboard;
При получении данных от клиента нужно обрабатывать событие onPokeData. В нашем случае нужно
просто отобразить переданные данные на одном из компонентов TMemo.
А теперь рассмотрим наглядный пример приложения Сервера. Начнем с процедуры создания формы:
При получении данных от Клиента отображаемых их в одном из компонентов TMemo:
Кнопка для отправки сообщения Клиенту. При нажатии на кнопку происходи присвоение текста, введенного
в другой компонент TMemo и его немедленная отправка Клиенту:
Так как Сервер и Клиент используются совместно, то при закрытии одного из них второй так и останется
запущенным. Для этого при закрытии приложения Сервера закрываем и приложение Клиента:
Trouble № 1: Мною была замечена одна очень не приятная вещь. Приложение
Сервера без проблем принимает многострочные данные от Клиента, а в свою очередь Клиент не "хочет"
принимать многострочные данных от Сервера. Именно поэтому я решил запретить нажатие клавиши Enter,
чтобы хоть как-то скрыть этот огромный недостаток.
Теперь попробуем создать приложение Клиента. Клиент предназначен для получения данных от приложения Сервера. Теоретически Клиентов может быть несколько. Создадим новый проект. Затем положить на форму стандартные и специальные компоненты присущие Клиенту:
Компонент TDdeClientConv также представляет собой сеанс передачи данных, а компонент
TDdeClientItem - сами передаваемые данные, которые также хранятся в свойствах Lines
- для отправки нескольких строк и Text - для отправки одной строки. Обычно приложение
клиента также содержит один компонент TDdeClientConv и несколько компонентов TDdeClientItem.
Эти компоненты используются совместно. Через свойство DdeConv компонент TDdeClientItem
связывается с компонентом TDdeClientConv. А через свойство DdeItem задается источник данных.
Для организации параметров соединения используются следующие свойства:
Имя Сервера принято указывать без расширения, хотя даже если и указать расширение, то это не вызовет ни какой ошибки.
Trouble № 2: Установить перечисленные свойства динамически, то есть
во время выполнения программы, скорее всего не получиться. Все эти команды будут просто игнорированы.
Это нужно делать на этапе конструирования формы через Инспектор объектов.
При установки свойств через Инспектор объектов нужно воспользоваться одним из свойств компонента TDdeClientConv: DdeService или DdeTopic. При этом заполнение полей одного свойства приведет к заполнению полей другого свойства. Также можно нажать кнопку "Paste Link", что приведет к автоматическому заполнению полей. Но, эта кнопка будет активна только в том случае, если приложение Сервера было хоть раз запущено ранее, то есть "сработал" метод CopyToClipboard. При помощи свойства ConnectMode можно управлять способ подключения к Серверу. Если это свойство установлено в ddeAutomatic, то подключение осуществляется автоматически, а если свойство установлено в ddeManual, то подключение осуществляется вручную и для нормальной работы приложения программисту придется самому описывать все операторы. Для этого нужно воспользоваться группой операторов SetLink, OpenLink, CloseLink и RequestData. Для того чтобы отправить текстовое сообщение на Сервер существуют две основные функции PokeData - для отправки на Сервер однострочных данных и функция PokeDataLines для отправки многострочных данных.
А теперь рассмотрим наглядный пример приложения Клиента. Начнем с процедуры создания формы:
Кнопка для отправки данных на Сервер. Данные отправляются двумя различными способами. При
отправке данных первым способ используется функция Trim для удаления не нужных пробелов,
потому что при получении данных эти пробелы могут быть интерпретированы как кавычки или любые
другие символы:
Процедура для отображения полученных данных от Сервера:
При закрытии приложения Клиента также закрываем и приложение Сервера:
Здесь также запрещаем использовании клавиши Enter:
В процессе написания и отладки программы иногда необходимо узнать некоторые данные о соединении.
Так, например, можно узнать имя Сервера:
А так можно узнать тему обмена данными и DdeServerItem:
|