OLE (664410), страница 2
Текст из файла (страница 2)
- почтовый ящик;
- динамический обмен данными;
- встраивание объектов.
Специальный почтовый ящик (clipboard) Windows позволяет
пользователю переносить информацию из одного приложения в другое,
не заботясь об ее форматах и представлении.
В отличие от профессиональных операциональных операционных
систем, где механизм обмена данными между программами доступен
только программисту, в Windows это делается очень просто и наг-
лядно для пользователя.
Механизм обмена данных между приложениями - жизненно важное
свойство многозадачной среды. И в настоящее время производители
программного обеспечения пришли уже к выводу, что для переноса
данных из одного приложения в другое почтового ящика уже недоста-
точно. Появился новый, более универсальный механизм - OLE (
Object Linking and Embedding )
- Встроенная объектная связь, который позволяет пе-
реносить из одного приложения в другое разнородные данные. Напри-
мер, с помощью этого механизма данные, подготовленные в системе
сетевого планирования Time Line for Windows ( Symantec ), можно
переносить в текстовый процессор Just Write ( Symantec ), а за-
тем, скажем, в генератор приложений Object Vision (Borland).
Правда, это уже нестандартное средство Microsoft Windows, но тем
не менее реализация OLE стала возможной именно в Windows.
Кроме механизма почтового ящика, предназначенного, в основ-
ном, для пользователя, программисту в Windows доступны спе-
циальные средства обмена данными между приложениями.
Программным путем можно установить прямую связь между зада-
чами, например, принимая данные из последовательного порта, авто-
матически помещать их, скажем, в ячейки электронной таблицы
Excel, средствами которой можно тут же отображать сложные зависи-
мости в виде графиков или осуществлять их обработку в реальном
режиме времени (этот механизм носит название динамического обме-
на данными - Dynamic Data Exchange, DDE ).
Основные термины
Клиентское приложение DDE - приложение, которому необходи-
мо установить диалог с сервером и получить данные от сервера в
процессе диалога.
DDE-диалог - взаимосвязь между клиентским и серверным при-
ложениями.
Сервер-приложение - DDE приложение, которое передает дан-
ные клиенту в процессе диалога.
DDE-Транзакция -обмен сообщениями или данными между клиен-
том и сервером.
Item имя - строка, идентифицирующая некоторое множество
данных, которое сервер в состоянии передать клиенту в процессе
диалога.
Service имя - строка, генерируемая сервером и используе-
мая клиентом для установления диалога.
Строковый указатель - двойное слово, генерируемое опера-
ционной системой, идентифицирующее строку, передающуюся в процес-
се динамического обмена данными.
Topic имя - строка, которая идентифицирует тип данных,
необходимых клиентскому приложению при динамическом обмене данных.
Фильтр транзакции - флаг, который препятствует передаче
нежелательных типов транзакций в функцию обратного вызова.
В Microsoft Windows динамический обмен данных является фор-
мой связи, которая использует общие области памяти для обмена
данными между приложениями. Приложение может использовать DDE в
некоторый момент времени для передачи и получения новых данных от
сервера.
Механизм DDE схож с механизмом почтового ящика, который яв-
ляется частью операционной системы WINDOWS. Существует лишь нез-
начительная разница в том, что почтовый ящик, в большинстве слу-
чае, используется как буфер временного хранения информации. DDE
может быть инициализирован пользователем и в большинстве случаев
продолжать работать без его вмешательства.
Библиотека DDEML обеспечивает пользователя набором средств,
которые упрощают использование механизма DDE в WINDOWS приложе-
ниях. Вместо того, чтобы обрабатывать, получать и передавать DDE
сообщения напрямую, приложения используют функции DDEML библиоте-
ки. Библиотека DDEML также обеспечивает работу со строками и раз-
деляемыми данными, генерируемыми DDE приложениями. Вместо того,
чтобы использовать указатели на общие области памяти, DDE прило-
жения создают и обмениваются строковыми указателями, которые
идентифицируют строки и данные.
Уже существующие приложения, использующие протокол DDE, ос-
нованный на сообщениях полностью совместимы с теми, которые ис-
пользуют библиотеку DDEML. Вот почему приложение, использующее
DDE-протокол могут установить диалог и выполнять транзакции с
приложениями, использующими библиотеку DDEML.
Взаимосвязь между клиентом и сервером.
DDE возникает всегда между клиентским приложением и сервер-
ным. Клиентское приложение инициализирует обмен данными путем ус-
тановления диалога с сервером и передачи транзакции. Транзакция
необходима для данных и обслуживания. Сервер отвечает на транзак-
цию и обеспечивает клиента данными. Сервер может иметь сразу нес-
колько клиентов в одно и тоже время, в свою очередь, клиент мо-
жет получать данные сразу от нескольких серверов. Некоторое при-
ложение одновременно может быть и клиентом и сервером. В добавок
к вышесказанному, клиент и сервер могут оборвать диалог в любое
удобное для них время.
DDE сервер использует три зарезервированных типа имен, рас-
положенных иерархично: service, topic item - уникально идентифи-
цируют некоторое множество данных, которое сервер может передать
клиенту в процессе диалога.
Service имя - это строка, которую генерирует сервер в те
промежутки времени, в которые клиент может установить диалог с
сервером.
Topic имя - это строка, которая идентифицирует логичес-
кий контекст данных. Для сервера, который манипулирует файлами,
topic имена это просто названия файлов; для других серверов - это
специфические имена конкретного приложения. Клиент обязательно
должен указывать topic имя вместе с service именем, когда он хо-
чет установить диалог с сервером.
Item имя - это строка, которая идентифицирует некото-
рое множество данных, которое сервер может передать клиенту в
процессе транзакции. Например, item имя может идентифицировать
ЦЕЛОЕ ( int, integer ), СТРОКУ ( string, char * ), несколько па-
раграфов текста, или BITMAP образ.
Все вышеуказанные имена позволяют клиенту установить диа-
лог с сервером и получить от него данные.
Системный режим
Системный режим работы обеспечивает клиента всей необходи-
мой информцией о сервере.
Для того, чтобы определить, какие серверы доступны в дан-
ный момент времени, а также какой информацией они могут обеспе-
чить клиента, последний, находясь в начальном режиме работы, дол-
жен установить имя устройства, равное NULL. Такой шаблон диалога
максимально увеличивает эффективность работы, а также работу с
сервером в системном режиме. Сервер, в свою очередь, должен под-
держивать нижеописанные item имена, а также другие, часто ис-
пользуемые клиентом:
SZDDESYS ITEM TOPICS - список item имен, с которыми может
работать сервер в данный момент времени. Этот список может изме-
няться время от времени.
SZDDESYS ITEM SYSITEMS - список item имен, с которыми мо-
жет работать сервер в системном режиме.
SZDDDESYS ITEM STATUS - запросить текущий статус сервера.
Обычно, данный запрос поддерживается только в формате CF_TEXT и
содержит строку типа Готов/Занят.
SZDDE ITEM ITEMLIST - список item имен, поддерживаемых сер-
вером в несистемном режиме работы. Этот список может меняться
время от времени.
SZDDESYS ITEM FORMATS - список строк, представляющий собой
список всех форматов почтового ящика, поддерживаемых сервером в
данном диалоге. Например, CF_TEXT формат представлен строкой TEXT.
Основное назначение и работа функции обратного вызова
Приложение, которое использует DDEML, должно содержать фун-
кцию обратного вызова, которая обрабатывает события, полученные
приложением. DDEML уведомляет приложение о таких событиях путем
посылки транзакций в функцию обратного вызова данного приложения.
В зависимости от флага фильтра транзакции, сформированного
при вызове функции DdeInitialize, функция обратного вызова полу-
чает отсортированные транзакции вне зависимости от того, являет-
ся ли данное приложение клиентом, сервером или тем и другим од-
новременно. Следующий пример демонстрирует наиболее типичное ис-
пользование функции обратного вызова.
HDDEDATA CALLBACK DdeCallback( uType, uFmt, hconv, hsz1,
hsz2, hdata, dwData1, dwData2 )
UINT uType; // Тип транзакции
UINT uFmt; // Формат почтого ящика
HCONV hconv; // Идентификатор диалога
HSZ hsz1; // Идентификатор строки #1
HSZ hsz2; // Идентификатор строки #2
HDDEDATA hdata; // Идентификатор глобального объек-
та памяти
DWORD dwData1; // Данные текущей транзакции #1
DWORD dwData2; // Данные текущей транзакции #2
{
switch (uType)
{
case XTYP_REGISTER:
case XTYP_UNREGISTER:
. . .
return (HDDEDATA) NULL;
case XTYP_ADVDATA:
. . .
return (HDDEDATA) DDE_FACK;
case XTYP_XACT_COMPLETE:
. . .
return (HDDEDATA) NULL;
case XTYP_DISCONNECT:
. . .
return (HDDEDATA) NULL;
default:
return (HDDEDATA) NULL;
}
}
Параметр uType идентифицирует тип посланной транзакции в
функцию обратного вызова при помощи DDEML. Значения оставшихся
параметров зависят от типов транзакции. Типы транзакций будут об-
суждены нами в разделе "Обработка Транзакций".
Диалог между приложениями
Диалог между клиентом и сервером всегда устанавливается по
требованию клиента. Когда диалог установлен, оба партнера полу-
чают идентификатор, который описывает данный диалог.
Партнеры используют этот идентификатор в большинстве фун-
кций DDEML для посылки транзакций и для их обработки. Клиенту мо-
жет потребоваться диалог как с одним сервером, так и с нескольки-
ми.
Рассмотрим подробно как приложение устанавливает диалог и
получает информацию о уже существующих каналах связи.
Простой Диалог
Клиентское приложение устанавливает простой диалог с серве-
ром путем вызова функции DdeConnect и определяет идентификаторы
строк, которые содержат всю необходимую информацию о service име-
ни текущего сервера и интересущем клиента в данный момент topic
имени.
DDEML отвечает на вызов этой функции посылкой соответствую-
щей транзакции XTYP_CONNECT в функцию обратного вызова каждого
доступного в данный момент времени сервера, зарегистрированное
имя которого совпадает с именем, переданным при помощи функции
DdeConnect при условии, что сервер не отключал фильтр service
имени вызовом функции DdeServiceName.
Сервер может также установить фильтр на XTYP_CONNECT тран-
закцию заданием соответствующего флага CBF_FAIL_CONNECTIONS при
вызове функции DdeInitialize.
В процессе обработки транзакции типа XTYP_CONNECT DDEML пе-
редает полученные от клиента service и topic имена серверу. Сер-
вер должен проверить эти имена и возвратить TRUE, если он в сос-
тоянии работать с такими именами, и FALSE в противном случае.
Если ни один из существующих серверов не отвечает на CONNECT-зап-
рос клиента, функция DDeConnect возвращает ему NULL с информа-
цией о том, что в данный момент времени НЕ возможно установить
диалог.
Однако, если сервер возвратил TRUE, то диалог был успешно
установлен и клиент получает идентификатор диалога
- двойное слово, посредством которого и ведется
обмен данными с сервером.
Затем сервер получает транзакцию вида XTYP_CONNECT_CONFIRM
(в случае, если он НЕ описывал флаг фильтра CBF_FAIL_CONFIRMS при
вызове соответствующей функции).
В нижеприведенном примере производится попытка установить
диалог с сервером, который в состоянии работать с service именем
'My Server' в системном режиме. Считаем, что параметры
hszSysTopic и hszServName уже предварительно созданы нами ранее.
HCONV hConv;
HWND hwndParent;
HSZ hszServName;
HSZ hszSysTopic;