Что такое dde сервер

Однако существуют директивы DDE, позволяющие передавать данные и от клиента к серверу. Кроме того, данные, посылаемые серверу, могут быть директивами, которые указывают серверу на необходимость выполнить некоторые действия, например открыть файл.

Применение DDE.

Таблица. Зарегестрированые имена программ, поддерживающих DDE

Программа Зарегистрированное имя

Word for Windows WinWord

Windows Program Manager ProgMan

Visual Basic for Windows имя_программы*

Открытие коммуникационного канала DDE.

Для инициализации связи между двумя выполняющимися программами используется метод DDEIniate, который имеет следующий синтаксис:

канал = DDEInitiate(программа, тема)

Аргументы программа и тема являются строками. Чтобы определить, какие значения аргументов используются, обратитесь к документации на программу. Этот метод возвращает номер канала, используемый в других командах Visual Basic для идентификации данного коммуникационного канала. При выполнении метода устанавливается соединение DDE между Visual Basic for Applications и другой программой.

Закрытие канала DDE.

После завершения использования канала DDE его необходимо закрыть с помощью метода DDETerminate, имеющего следующий синтаксис:

Получение информации от сервера.

Чтобы запросить данные от сервера по открытому коммуникационному каналу, используется метод DDERequest, имеющий следующий синтаксис:

Переменная = DDERequest(канал, элемент)

Dim ChannelNum As Integer

‘Установление связи DDE с Word и получение предложения.

‘Запуск Word и открытие документа 26VBAOR.DOC

‘Замените имя документа и путь на атрибуты одного из ваших документов

ChannelNum = DDEInitiate (“WinWord”, “I:\BHV_VBA\26BAOR.DOC”)

‘Отображение номера канала в диалоговом окне.

Results = DDERequest (ChannelNum, “BookMark1”) ‘Запрос данных.

‘Отображение данных в диалоговом окне.

DialogSheets (“DDEDialog”). EditBoxes (“DDEDataBox”). Text = Results

Создайте страницу диалога, назовите её DDEDialog; добавьте к ней три командные кнопки, две метки и два текстовых окна. Назовите текстовое окно, расположенное под меткой «Результат», DDEDataBox, а второе текстовое окно – DDEChannelBox. Для подключения командной кнопки “Открыть DDE” к процедуре OpenChannel, командной кнопки “Принять данные” – к процедуре GetData и командной кнопки “Закрыть DDE” – к процедуре CloseChannel используйте директиву Tools/Assign Macro.

На пиктографическом меню Forms нажмите пиктограмму Run Dialog, затем на бланке нажмите командную кнопку “Открыть DDE”. Нажатие этой кнопки инициирует выполнение процедуры OpenChannel, которая открывает канал к программе Word for Windows (WinWord), затем запрашивает документ 26BAOR.DOC и отображает номер канала в окне DDEChannelBox.

Нажатие командной кнопки “Принять данные” инициирует выполнение процедуры GetData, запрашивающей содержимое закладки BookMark1. Если текст закладки будет обнаружен, то он отобразится в окне DDEData.

С Для закрытия канала DDE нажмите командную кнопку “Закрыть DDE”.

Передача информации серверу.

Чтобы послать информацию серверу, используется метод DDEPoke. Этот метод имеет следующий синтаксис:

DDEPoke (канал, элемент, данные)

Для примера, добавьте процедуру, посылающую программе Word некоторый текст, который заменяет текст, маркированный как закладка BookMark1. Вначале добавьте к бланку командную кнопку “Послать данные”. Затем подключите эту кнопку к следующей процедуре:

‘Копирование данных из диалогового окна в ячейку таблицы.

Sheets (“Sheet1”). Cells(1, 1). Formula = _

‘Создание ссылки на ячейку таблицы.

Set Result = Sheets(“Sheet1”). Cells(1, 1)

‘Пересылка ссылки на ячейку связанной программе для замены текста, маркированного как

Application.DDEPoke ChannelNum, “BookMark1”, Result

Передача директив серверу.

Перешлите программе Word директиву File/Print Preveiw. Для этого добавьте кдиалоговому окну «Тестер DDE» командную кнопку «ПредПросмотр» и подключите ее к следующей процедуре:

‘ Пересылка связанной програме директивы предварительного просмотра.

Технология OLE

OLE имеет значительно больше возможностей, чем DDE. Если DDE просто обеспечивает обмен данными между программами, то OLE позволяет передавать объекты. Существуют 2 различных типа OLE: Linking and Embedding (Связь и внедрение) и OLE Automation(Автоматизация OLE).

OLE Automation позволяет одному объекту управлять другой программой посредством доступа к ее объектам и методам. При использовании OLE Automation Объекты и методы подключенной программы становятся расширением языка Visual Basic.

Применение OLE Automation

Теперь вы можете использовать Object Browser для изучения объектов другой программы. Кроме того, Object Browser отображает имя, под которым зарегестрирована в системе данная программа.

Объекты другой программы могут иметь те же имена, что и объекты в вашей программе; следовательно, для доступа надежнее пользоваться полными именами. Например если вы запустите MS Excell VBA и выполните оператор APPlication.Name

то получите имя Excell. Но если вы выполните оператор

то получите имя Project.

Для доступа к любому объекту, находящемуся вне текущей программы, используете полную ссылку, что не только даст возможность уверенно получить нужный объект, но и повысить читабельность вашей программы.

Создание и открытие объектов.

Метод Createobject имеет синтаксис

Set объектная_переменная = Createobject(класс)

где объектная_переменная представляет собой любую переменную типa Object или Variant, а класс является классом создаваемого объекта. Аргумент класс состоит из двух частей, разделенных точкой:

Так следующий оператор запускает Excell и создает новую таблицу:

Set Xlsheet = createObject(«Excell.Sheet»)

Если Excell уже запущен и рабочая папка уже открыта, то оператор добавит новую таблицу к открытой рабочей папке. Если Excell не запущен, то оператор запускает Excell с новой рабочей папкой.

Следующий оператор запускает Word и возвращает объект, на который можно ссылаться как на Word Basic:

Set WordSheet = createObject(«Word.Basic»)

Метод GetObject открывает существующий объект. Метод имеет синтаксис:

Set объектная_переменная = GetObject(Имя_файла,класс)

Например следующий оператор открывает таблицу COST.XLS в директории PROJ диска D:

Set Xlsheet = GetObject(«D:\PROJ\COST.XLS», «Excell.Sheet»)

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого.

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций.

Источник

Использование платформа динамических данных Exchange

В этом разделе приведены примеры кода для следующих задач:

Инициация диалога

В следующем примере показано, как клиент инициирует диалог, где указаны и приложение, и раздел.

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

Серверные приложения реагируют в соответствии с логикой, показанной на следующей схеме.

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Чтобы подтвердить один или несколько разделов, сервер должен создать атомы для каждого диалога (если существует несколько разделов) и отправить сообщение WM _ DDE _ ACK для каждого диалога, как показано в следующем примере.

Передача одного элемента

Получение элемента с сервера

Чтобы получить элемент с сервера, клиент отправляет серверу сообщение _ _ запроса WM DDE с указанием элемента и формата для извлечения, как показано в следующем примере.

В этом примере клиент указывает формат буфера обмена в формате CF _ в качестве предпочтительного формата для запрошенного элемента данных.

Получатель (сервер) сообщения _ _ запроса DDE WM обычно должен удалить элемент Atom, но если вызов сообщения завершается неудачей, клиент должен удалить Atom.

Поскольку разблокировка данных делает указатель на данные недействительным, клиент сохраняет значение члена фрелеасе перед разблокировкой объекта данных. После сохранения значения клиент проверяет его, чтобы определить, запросил ли клиентское серверное приложение освобождение памяти, содержащей данные. Клиент действует соответствующим образом.

Если сервер поддерживает элемент formats системного раздела, клиент может определить, какой именно формат буфера обмена поддерживает сервер, а не определять их каждый раз, когда клиент запрашивает элемент.

Отправка элемента на сервер

Установка постоянного канала данных

Клиентское приложение может использовать DDE для установки ссылки на элемент в серверном приложении. После того как такая связь установлена, сервер отправляет периодические обновления связанного элемента клиенту, как правило, при каждом изменении значения элемента. Таким словами, между двумя приложениями устанавливается постоянный поток данных; Этот поток данных остается на месте до тех пор, пока он не будет явно отключен.

Инициация связи с данными

В этом примере клиентское приложение устанавливает флаг фдеферупд для сообщения WM _ DDE _ advise в значение false. Это направляет серверное приложение на отправку данных клиенту при каждом изменении данных.

Сообщение WM _ DDE _ advise устанавливает формат данных, которые будут передаваться на сервер при связи. Если клиент пытается установить другую связь с тем же элементом, но использует другой формат данных, сервер может отклонить второй формат данных или попытаться его поддерживать. Если для какого-либо элемента данных была установлена горячая связь, сервер может одновременно поддерживать только один формат данных. Это связано с тем, что сообщение _ _ данных WM DDE для горячего соединения имеет пустой обработчик данных, который в противном случае содержит сведения о формате. Таким же, сервер должен отклонять все горячие связи для элемента, который уже связан, и отклонять все ссылки для элемента, для которого имеются горячий ссылки. Другой интерпретацией может быть то, что сервер изменяет формат и горячее или теплое состояние ссылки при запросе второй ссылки на тот же элемент данных.

В общем случае клиентские приложения не должны пытаться одновременно устанавливать несколько ссылок на один элемент данных.

Запуск связи с данными с помощью команды «вставить ссылку»

Приложения, поддерживающие каналы «горячий» или «теплый» канал данных, обычно поддерживают зарегистрированный формат буфера обмена с именем Link. При сопоставлении с командами копирования и вставки в приложении этот формат буфера обмена позволяет пользователю устанавливать сеанс DDE между приложениями просто путем копирования элемента данных в серверное приложение и вставки его в клиентское приложение.

Один символ NULL отделяет имена, а два пустых символа завершают всю строку.

Клиентские и серверные приложения должны зарегистрировать формат буфера обмена ссылок, как показано ниже.

Ниже приведен пример ответа клиентского приложения, когда пользователь выбирает команду Вставить ссылку.

В этом примере клиентское приложение открывает буфер обмена и определяет, содержит ли он данные в формате ссылки (т. е. Кфлинк), который был ранее зарегистрирован. Если это не так или не может блокировать данные в буфере обмена, клиент возвращает.

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

Клиентское приложение определяет, существует ли связь между этим разделом и серверным приложением. Если диалог существует, клиент проверяет, существует ли уже ссылка для элемента данных. Если такая ссылка существует, клиент отображает окно сообщения пользователю. в противном случае он вызывает собственную функцию сендадвисе для отправки на сервер сообщения с сообщением об ошибке WM _ DDE _ для элемента.

Уведомление клиента об изменении данных

Когда клиент устанавливает связь с набором элементов фдеферупд (то есть равным 1), клиент запрашивает, чтобы каждый раз при изменении данных отправлялись только уведомления, а не сами данные. В таких случаях при изменении значения элемента сервер не отображает значение, но просто отправляет клиенту сообщение _ _ данных WM DDE с нулевым маркером данных, как показано в следующем примере.

Завершение связи с данными

Сообщение WM _ DDE _ unadvise указывает формат данных. Нулевой формат информирует сервер о необходимости присоединения всех ссылок для указанного элемента, даже если установлено несколько активных ссылок и используется другой формат.

Выполнение команд в серверном приложении

Завершение диалога

Как клиент, так и сервер могут выдавать сообщение о _ _ прерывании WM DDE для завершения диалога в любое время. Аналогично, как клиентские, так и серверные приложения должны быть готовы к получению этого сообщения в любое время. Перед завершением работы приложение должно завершить все его диалоги.

После того как приложение отправило сообщение об _ _ увольнении WM DDE участнику в сеансе DDE, оно не должно отвечать на сообщения от этого участника, так как участник мог уничтожить окно, в которое был отправлен ответ.

Источник

dde server window что это

Dynamic Data Exchange (DDE) — механизм взаимодействия приложений в операционных системах Microsoft Windows и OS/2. Хотя этот механизм до сих пор поддерживается в последних версиях Windows, в основном он заменён на более мощные механизмы — OLE, COM и Microsoft OLE Automation. Однако, DDE по-прежнему используется в некоторых местах внутри самой Windows, в частности, в механизме ассоциации расширения имени файла с приложениями. Это является следствием модели разработки, в которой Microsoft в новых версиях ОС Windows следит за обеспечением совместимости со всеми её предыдущими версиями. Возможно использование для извлечения данных из сторонних приложений.

DDE — давний и прижившийся протокол обмена данными между разными приложениями, появившийся еще на заре эры Windows. С тех пор на его базе был создан интерфейс OLE, а в 32-разрядном API Windows появились и другие методы межпрограммного взаимодействия. Но ниша, занимаемая DDE, осталась неизменной — это оперативная передача и синхронизация данных в приложениях.

Приложения, использующие DDE, разделяются на две категории — клиенты и серверы (не путать с одноименной архитектурой СУБД). Оба участника процесса осуществляют контакты (conversations) по определенным темам (topic), при этом в рамках темы производится обмен элементами данных (items). Устанавливает контакт клиент, который посылает запрос, содержащий имена контакта и темы. После установления контакта всякое изменение элемента данных на сервере передается данным клиента.

Первоначально программирование DDE было чрезвычайно сложным делом — оно требовало взаимосвязанной обработки более чем десяти сообщений Windows. В версии Windows 3.1 появилась библиотека DDEML, которая перевела управление DDE на уровень вызова процедур. Разработчики подсистемы DDE в Delphi, верные идеологии создания VCL, свели интерфейс этого протокола к четырем компонентам — двум для сервера и двум для клиента.

На уровне поддержания контакта лежат компоненты TDDEServerConv и TDDEClientConv. Первый играет пассивную роль — он только указывает имя одной из поддерживаемых сервером тем. Все операции по установлению и разрыву контакта осуществляет из приложения-клиента второй компонент.

Обмен данными по протоколу DDE состоит из трех этапов:

Каких-то особенностей, характерных именно для протокола DDE, здесь, как видите, нет: можно легко провести параллели между протоколом DDE и файлами (открытие, работа, закрытие), между протоколом DDE и протоколом TCP (установка соединения, обмен данными, разрыв соединения) и т.д. В процессе установки соединения один из участников является его инициатором (в терминологии DDE — клиентом), а второй находится в постоянной готовности к установке соединения (в терминологии DDE — сервер). И сервер, и клиент — это некие приложения (упрощенно — *.exe-файлы), запущенные на одном или на разных компьютерах, хотя одно и то же приложение в принципе может являться одновременно и сервером, и клиентом протокола DDE (пример такого приложения — электронные таблицы Microsoft Excel). Со стороны клиентского приложения каких-либо предварительных действий в протоколе DDE делать не требуется, а вот серверное приложения должно сначала зарегистрироваться в Windows в качестве сервера протокола DDE. Если этого не сделать, клиент DDE не сможет подсоединиться к серверу. Сервер DDE при регистрации сообщает Windows то имя, под которым он будет «известен» на данном компьютере. В терминологии DDE это имя называется Application. Разработчики DDE-серверов обычно стараются сделать это имя совпадающим с именем самого приложения, например Application-имя упомянутых выше таблиц Microsoft Excel — «EXCEL», DDE-сервер системы Intouch имеет имя «VIEW» и т.д. В принципе, имя для своего DDE-сервера можно задавать любое, лишь бы оно вписывалось в традиционные понятия об имени (латинские буквы, цифры, знаки подчеркивания) и имело длину не более 8 символов. Именно по этому имени и будет подсоединяться к серверу клиент DDE-протокола.

Посредством одного контакта могут быть связаны и синхронизированы несколько пар элементов данных. Для их описания предназначены компоненты TDDEServerItem и TDDEClientItem. Каждый из них во время работы должен указывать на контакт, к которому он привязан. Кроме того, в составе обоих есть свойства, содержащие некий текст. При установленном контакте их содержимое синхронизируется. Помимо этого в модуле DDEMAN описан и пятый компонент, который управляет всеми связями DDE.

DDEML

Win32 API включает библиотеку DDEML

Поскольку Win32 API имеет архитектуру, построенную на обработке сообщений, то использование сообщений — наиболее подходящий метод для автоматической передачи информации между приложениями. Тем не менее, сообщения Win32 содержат только два параметра (wParam, lParam) для передачи данных. В этом Вы можете убедиться прочитав пример для среды Delphi, в котором используется функция посылки сообщения. В результате, эти параметры должны косвенно указывать на передаваемые данные. Протокол DDE определяет точно, как приложения должны использовать wParam и lParam параметры, чтобы передать данные. Протокол DDE имеет специфические правила для распределения и удаления передаваемых объектов.

…DDE Доступ к HID-устройствам Источник бесперебойного питания если есть, то не отключаем Оповещатель Планировщик заданий Сервер папки обмена Служба сетевого DDE Служба сообщений Удаленный реестр Центр обеспечения безопасности можете не отключать, но…
Почему компьютер зависает?

…LM Обеспечивает безопасность программам, использующим удаленные вызовы процедур (RPC) через транспорты, отличные от именованных каналов. Вручную entercad Сервер папки обмена Позволяет просматривать страницы папок обмена удаленных компьютеров. Вручную entercad Сетевой вход……удаленной сети, когда программа обращается к удаленному DNS- или NetBIOS-имени или адресу. Вручную entercad Диспетчер сетевого DDE Управляет разделяемыми объектами динамического обмена данными и используется сетевым DDE Вручную entercad Диспетчер служебных…
Подскажите. На компе куча левых служб.

…А так — в администрирование, в службы, и отключить/запретить все что жить мешает. Ну на кой тебе DDE сервер не на серванте?…
Компьютер сильно тормозит.При выключении вылетает окошко «Завершение DDE Server»Что это?

…обновление,Беспроводная настройка,Брандмауэр Windows/Общий доступ к Интернету (ICS),Веб-клиент,Вторичный вход в систему,Диспетчер сетевого DDE,Источник бесперебойного питания,Клиент отслеживания изменившихся связей,Маршрутизация и удаленный доступ,Модуль поддержки NetBIOS через TCP/IP,Обозреватель компьютеров,Оповещатель,Планировщик заданий,Сервер,Сервер папки обмена,Система событий COM+,Системное приложение COM+,Служба времени Windows,Служба обнаружения…
Какие службы Вы отключали безболезненно для системы, поделитесь, пожалуйста, опытом?

…Получаю данные в Эксель через DDE сервер (каждую секунду значение в ячейке меняется). Необходимо сделать историю из последних 100 значений….
Эксель — как сделать аналогию стека?

…служба ) Служба восстановления системы (после установки сделать резервную копию системы с помощью сторонней программы) Сетевой вход в систему Сервер папки обмена Сервер Оповещатель Где-то так Вообще надо смотреть по компу Что ему……Справка и поддержка (кому как ) Совместимость быстрого переключения пользователей (тоже кому как) Службы терминалов Служба сообщений Служба сетевого DDE Служба общих сетевых ресурсов проигрывателя Windows Media Служба индексирования (вообще тупорылая служба ) Служба восстановления… Сервер DDE
какие системные службы на windows xp лучше отключить?

…Зайди в панели управления в Администрирование—>Службы поищи в списке Служба сетевого DDE может она включена? Кстати Сервер папки обмена тож тогда выруби, если в локалке ничего не расшариваешь….
Что такое DDE Server Window Достал уже, всякий раз во время перезагрузки сообщает, что не может завершить работу и

…если не один из ваших программ защиты его не использует. )По моему у Каспера есть свой… Сервер папки обмена * Служба COM записи компакт-дисков IMAPI (только если вы не пользуетесь встроенные……доступ к Интернету (ICS) * Веб-клиент * Вторичный вход в систему (если вы единственный пользователь на компе) * Диспетчер сетевого DDE * Доступ к HID-устройствам * Координатор распределенных транзакций * Маршрутизация и удаленный доступ * Модуль поддержки NetBIOS…
Как увеличить быстродействие компа?

Источник

Операционная система Microsoft Windows 3.1 для программиста. Дополнительные главы

3. Обмен данными через DDE

Операционная система Windows предоставляет пользователю возможность запустить одновременно несколько приложений. Как правило, пользователь именно так и поступает. Однако сама по себе эта достаточно важная особенность Windows не имела бы столь большого значения, если бы не существовали удобные механизмы обмена данными между приложениями.

В предыдущей главе мы рассмотрели возможность передачи данных из одного приложения в другое через универсальный буфер обмена Clipboard. При этом обмен данными носит эпизодический характер и находится под контролем пользователя. Пользователь выделяет фрагмент документа, копирует его в Clipboard и затем вставляет в другой или тот же самый документ.

Однако существуют и другие способы передачи данных между приложениями.

Предметом нашего изучения в этой главе будет механизм динамического обмена данными DDE (Dynamic Data Exchange), позволяющий создать постоянно действующие каналы между несколькими одновременно работающими приложениями Windows. Эти каналы могут создаваться автоматически при запуске приложения или при необходимости, а также по явному запросу пользователя. После того как каналы созданы, они будут работать без вмешательства пользователя.

В операционной системе Windows версии 3.0 механизм DDE был реализован через передачу сообщений с помощью хорошо известной вам функции SendMessage с использованием глобальных блоков памяти, доступных всем приложениям. Фактически при создании DDE-приложений программист был вынужден вникать во все детали процесса создания канала связи, придерживаясь определенного в SDK протокола. Поэтому использованию динамического обмена данных DDE сопутствовали многочисленные затруднения.

Библиотека DDEML хороша сама по себе, так как она упрощает DDE-приложения и избавляет программиста от учета утомительных деталей протокола обмена сообщениями. Однако есть еще две причины, по которой следует пользоваться этой библиотекой.

Во-первых, в новых версиях Windows, а также в операционной системе Windows NT динамический обмен данных организуется исключительно с помощью библиотеки DDEML. Поэтому если в будущем вы собираетесь переносить свое приложение в среду Windows NT или Windows-95, имеет смысл сразу ориентироваться на работу с DDEML.

Во-вторых, вспомним о существовании такой операционной системы, как Windows for Workgroups. Сетевые возможности Windows for Workgroups базируются на сетевом динамическом обмене данными Network DDE (операционная система Windows NT также поддерживает Network DDE).

Механизм Network DDE позволяет организовать каналы обмена данными между приложениями, которые запущены на разных рабочих станциях сети. Поэтому освоение «обычной» библиотеки DDEML можно считать первым шагом на пути к изучению сетевых возможностей различных версий Windows.

Исходя из сказанного выше, мы считаем нецелесообразным изучение устаревшего протокола обмена сообщениями DDE. Вместо этого мы сразу займемся библиотекой DDEML, ставшей стандартным средством организации динамического обмена данными в операционной системе Windows.

3.1. Архитектура «клиент-сервер»

Прежде всего, определимся с терминологией.

Клиентом и сервером мы будем называть процессы (программы или приложения), работающие одновременно на одном или разных компьютерах (объединенных в сеть), и взаимодействующих между собой определенным образом.

Клиент посылает серверу запрос на получение данных или выполнение какой-либо работы (рис. 3.1). Это может быть запрос к серверу базы данных, задание серверу резервного копирования дисков или что-то аналогичное.

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.1. Взаимодействие между клиентом и сервером

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

Процесс передачи запроса серверу мы будем называть транзакцией.

Транзакция называется завершенной, если выполнены все три действия. Если же на одном из трех этапов произошел сбой, транзакция останется незавершенной. После восстановления незавершенная транзакция откатывается, что необходимо в ряде случаев для сохранения целостности данных (разумеется, за правильное выполнение отката транзакции отвечает сервер).

Например, если сервер базы данных получил от клиента запрос на обновление записей в нескольких файлах и перед аварийным отключением электропитания успел выполнить только часть работы, после восстановления ему необходимо восстановить состояние базы данных на момент начала незавершенной транзакции.

Топология системы, имеющей архитектуру «клиент-сервер», может быть различной. На рис. 3.1 показана система, состоящая из одного клиента и одного сервера. Однако в системе может быть несколько клиентов, работающих с одним сервером (рис. 3.2), или несколько клиентов, работающих одновременно с несколькими серверами (рис. 3.3).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.2. Система с одним сервером и несколькими клиентами

Обратите внимание на пунктирную линию, соединяющую серверы на рис. 3.3. Между серверами тоже может идти обмен транзакциями. Таким образом, любой процесс может выступать одновременно и клиентом, и сервером.

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.3. Система с двумя серверами и несколькими клиентами

Очень хорошо, скажете вы, но причем тут DDE?

Библиотека DDEML позволяет создавать системы, имеющие различные топологии. В среде Windows версии 3.1 в качестве клиентов и серверов могут выступать приложения, работающие на одном компьютере. В локальной сети, созданной на базе операционных систем Windows for Workgroups и Windows NT, клиентами и серверами могут быть приложения, работающие на разных компьютерах.

3.2. Инициализация и создание канала связи

В процессе инициализации сервер должен выполнить такие действия:

зарегистрировать себя в библиотеке DDEML;

зарегистрировать предоставляемый сервис, которым сможет воспользоваться приложение-клиент

Клиент должен сделать следующее:

зарегистрировать себя в библиотеке DDEML;

создать канал связи с сервером, указав необходимый сервис

Рассмотрим эти действия подробнее.

Регистрация в библиотеке DDEML

Библиотека DDEML используется одновременно многими приложениями, однако, подобно всем DLL-библиотекам, находится в оперативной памяти в единственном экземпляре. Функция LibMain, выполняющая инициализацию DLL-библиотеки, вызывается только один раз при первой загрузке библиотеки в память (для Windows версии 3.1), поэтому LibMain не может использоваться для регистрации приложений.

Если приложение собирается использовать DDEML, оно должно зарегистрировать себя в библиотеке DDEML, вызвав специально предназначенную для этого функцию с именем DdeInitialize.

Прототип функции DdeInitialize определен в файле ddeml.h (который должен быть включен в исходный текст DDEML-приложения наряду с файлом windows.h):

UINT WINAPI DdeInitialize(

DWORD FAR* pidInst, // адрес идентификатора приложения

PFNCALLBACK pfnCallback, // адрес функции обратного вызова

Функция DdeInitialize используется в процессе инициализации и серверов, и клиентов DDEML. Сама по себе она не создает никаких каналов передачи данных между приложениями, однако процедура регистрации приложения, выполняемая этой функцией, должна быть проведена до вызова любых других функций, имеющих отношение к DDEML.

Займемся параметрами функции DdeInitialize.

Параметр pidInst представляет собой указатель на двойное слово, в которое после регистрации будет записан идентификатор, присвоенный копии приложения библиотекой DDEML (одновременно могут работать несколько копий одного и того же DDEML-приложения). Иными словами, в процессе регистрации библиотека DDEML присваивает копии приложения некоторый идентификатор, под которым она его «знает». Вы должны указывать полученный от функции идентификатор при вызове всех остальных функций библиотеки DDEML.

Перед вызовом функции DdeInitialize ваше приложение должно записать в двойное слово, адрес которого передается через первый параметр, нулевое значение.

Параметр pfnCallback представляет собой указатель на функцию обратного вызова, определенную приложением для обработки транзакций. Как сервер, так и клиент должны определить такую функцию. Функция обратного вызова вызывается системой DDEML и содержит в себе всю логику обработки транзакций, определенную вами при разработке приложения.

Если приложение вызывает функцию DdeInitialize несколько раз для многократной регистрации, каждый раз следует указывать отдельную функцию обратного вызова. Многократная регистрация вполне допустима, так как каждый раз библиотека DDEML будет создавать для себя новый идентификатор приложения. Такая методика используется при создании DLL-библиотек, работающих с DDEML. Обычным приложениям достаточно зарегистрировать себя один раз и, соответственно, определить одну функцию обратного вызова.

Через параметр afCmd передается двойное слово, каждый бит которого является флагом, определяющим режимы работы канала связи, а также влияющие на действия, выполняемые функцией DdeInitialize.

Последний параметр с именем ulRes зарезервирован и должен иметь нулевое значение.

Приведем фрагмент кода, выполняющего регистрацию сервера в библиотеке DDEML:

В этом фрагменте вначале создается переходник для функции обратного вызова, затем адрес этого переходника указывается во втором параметре функции DdeInitialize.

В случае успеха функция DdeInitialize возвращает нулевое значение. Для проверки можно также использовать константу DMLERR_NO_ERROR, определенную в файле ddeml.h. Если произошла ошибка, возвращается ненулевой код ошибки. Соответствующие константы определены в файле ddeml.h и имеют префикс имени DMLERR.

Немного о флагах, передаваемых через параметр afCmd.

Символические константы с префиксом имени APPCLASS позволяют задать класс приложения с точки зрения использования DDEML.

Класс APPCLASS_STANDARD предназначен для регистрации стандартного DDEML-приложения. Этот класс использован в приведенном выше фрагменте кода и в приложении DDEMLSR, исходные тексты которого вы увидите позже.

Класс APPCLASS_MONITOR предназначен для отладчиков и других приложений, управляющих работой системы DDEML. В качестве примера можно привести приложение DDESpy. Это приложение поставляется в составе Microsoft SDK for Windows 3.1 и предназначено для отладки DDE-приложений (и, разумеется, DDEML-приложений). В конце данной главы мы научим вас использовать приложение DDESpy для отладки созданных вами DDE-приложений.

Символические константы с префиксом имени APPCMD позволяют конкретизировать функции, выполняемые приложением, и экономить системные ресурсы. Если DDEML-приложение выполняет только функции клиента, следует указать флаг APPCMD_CLIENTONLY:

В простейших случаях можно ограничиться использованием класса APPCLASS_STANDARD при создании сервера DDEML и флага APPCMD_CLIENTONLY при создании клиента DDEML. Мы так и поступили в наших приложениях DDEMLSR и DDEMLCL, выполняющих, соответственно, функции сервера и клиента DDEML. Остальные флаги влияют на то, когда и зачем будет вызываться функция обратного вызова.

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

Регистрация сервиса

Следующий этап в инициализации сервера DDEML заключается в регистрации предоставляемого им сервиса.

Сервер DDEML может предоставлять сервис одного или нескольких видов. Как правило, один сервер предоставляет только один сервис, причем текстовая строка, идентифицирующая сервис, часто совпадает с именем приложения. Но можно выбрать любую другую строку. Например, наше приложение DDEMLSR предоставляет сервис «BMPService». Как можно догадаться из названия, этот сервис связан с bmp-файлами (в действительности мы привели сильно упрощенную версию сервера bmp-файлов, в которой для сокращения объема листингов изъяты функции обслуживания bmp-файлов).

Канал DDEML служит для передачи блоков данных. В рамках одного раздела сервер может обмениваться с клиентом разными блоками данных, каждый из которых идентифицируется при передаче именем элемента данных. В процессе создания канала связи не требуется указывать элементы данных.

Для иллюстрации сказанного выше предположим, что мы создаем сервер BMPSERV.EXE, предназначенный для отображения битовых изображений DIB, причем путь к соответствующему bmp-файлу и управляющая информация должны передаваться серверу через канал связи DDE.

При регистрации сервер BMPSERV.EXE регистрирует один сервис «BMPServer» и два раздела: «BMPFile» и «Control» (рис. 3.4).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.4. Сервис, разделы и элементы данных для сервера BMPSERV

В разделе «BMPFile» определены элементы данных «Filename» (имя отображаемого bmp-файла) и «Title» (заголовок изображения или подпись под изображением). В разделе «Control» определен один элемент данных «Mode», определяющий режим отображения (размеры и расположение окна, органы управления для работы с изображением и т. п.).

Разумеется, предложенная схема не единственно возможная и даже не самая простая. В нашем случае можно было ограничиться одним каналом, передавая по нему либо путь к файлу, либо управляющую информацию, имеющую отношение к отображению содержимого файла.

Регистрация сервиса выполняется сервером DDEML обычно сразу после вызова функции DdeInitialize и выполняется в два этапа.

На первом этапе текстовая строка имени сервиса сохраняется в специальной системной таблице (таблице атомов), для чего вызывается функция DdeCreateStringHandle:

Через параметр idInst приложение должно передать идентификатор, полученный на этапе регистрации приложения в библиотеке DDEML функцией DdeInitialize.

Параметр psz представляет собой указатель на текстовую строку, закрытую двоичным нулем. Размер этой строки не должен превышать 255 байт.

В качестве значения для параметра iCodePage можно указать CP_WINANSI (эта константа равна нулю). Можно также использовать значение, полученное от функции GetKBCodePage. Функция GetKBCodePage не имеет параметров и возвращает номер текущей кодовой страницы.

Идентификатор текстовой строки, возвращенный функцией DdeCreateStringHandle и соответствующий регистрируемому сервису, следует передать функции DdeNameService:

Через параметр idInst приложение должно передать идентификатор, полученный на этапе регистрации приложения в библиотеке DDEML функцией DdeInitialize.

Параметр hsz1 предназначен для передачи имени сервиса через идентификатор текстовой строки, возвращенной функцией DdeCreateStringHandle.

Параметр hsz2 зарезервирован, для него следует использовать нулевое значение.

При регистрации сервиса через параметр afCmd следует передать значение DNS_REGISTER (регистрация сервиса). Сервер DDEML в процессе своей работы может динамически регистрировать и отменять виды предоставляемого сервиса. Для отмены сервиса через параметр afCmd передается значение DNS_UNREGISTER.

Перед завершением работы сервер DDEML должен отменить весь зарегистрированный им ранее сервис, вызвав функцию DdeInitialize с параметром afCmd, имеющим значение DNS_UNREGISTER.

Приведем фрагмент кода, выполняющего регистрацию сервиса «BMPServer»:

Одновременно с регистрацией сервиса сервер обычно создает идентификаторы текстовых строк, содержащих имена используемых разделов и элементов данных. Для этого вызывается все та же функция DdeCreateStringHandle:

Отметим, что регистрацию сервиса выполняет только сервер DDEML. Что же касается создания идентификаторов текстовых строк функцией DdeCreateStringHandle, то эта операция выполняется как сервером, так и клиентом. Полученные идентификаторы используются при создании канала и в процессе передачи данных.

Зная идентификатор строки, приложение может получить строку, вызвав функцию DdeQueryString:

Назначение параметров понятно из комментариев в прототипе функции.

Если идентификатор созданной текстовой строки используется в функции обратного вызова (которую мы рассмотрим чуть позже), за освобождение ресурсов, связанных с текстовой строкой, отвечает система DDEML. В противном случае приложение должно самостоятельно уничтожать созданные им идентификаторы, вызывая функцию DdeFreeStringHandle:

Функция обратного вызова DDEML

Когда сервер или клиент регистрирует себя в библиотеке DDEML при помощи функции DdeInitialize, он указывает адрес переходника, созданного для функции обратного вызова. Функция обратного вызова предназначена для обработки всех событий, возникающих в процессе создания каналов связи и передачи данных.

В простейшем случае функция обратного вызова сервера DDEML может выглядеть следующим образом:

Функция обратного вызова должна быть определена как экспортируемая, поэтому мы указали ключевое слово _export.

Через первый параметр wType передается код транзакции. Подобно функции окна, которая обрабатывает сообщения, функция обратного вызова DDEML выполняет обработку транзакций. В зависимости от кода транзакции и результата обработки функция обратного вызова DDEML возвращает то или иное значение.

Второй параметр задает код формата передаваемых данных. Для кодов формата используются те же значения, что и для форматов Clipboard, например, CF_TEXT.

Через параметр hConv передается идентификатор канала передачи данных (который мы еще не научились создавать).

Назначение остальных параметров функции обратного вызова зависит от кода транзакции. В приведенном выше фрагменте кода используются символические имена кодов транзакций, определенные в файле ddeml.h, и имеющие префикс имени XTYP. В дальнейшем мы подробно расскажем о некоторых транзакциях, использованных в наших приложениях.

Функция обратного вызова для клиента DDEML выглядит точно также, отличаясь лишь составом обрабатываемых транзакций. Приведем для примера исходный текст такой функции из нашего приложения DDEMLCL:

При регистрации приложения в библиотеке DDEML функцией DdeInitialize можно указать флаги, запрещающие или разрешающие поступление транзакций некоторых типов в функцию обратного вызова. Запретив вызов функции обратного вызова для необрабатываемых транзакций, можно ускорить работу приложения.

Создание и уничтожение канала

Кто является инициатором создания канала?

Канал связи между клиентом и сервером создается всегда по инициативе клиента. После регистрации в библиотеке DDEML клиент вызывает функцию DdeConnect, создающую канал связи:

Через параметр idInst приложение должно передать идентификатор, полученный на этапе регистрации приложения в библиотеки DDEML функцией DdeInitialize.

Параметры hszService и hszTopic предназначены для передачи идентификаторов строк, содержащих, соответственно, имена сервиса и раздела. Эти идентификаторы были получены нами ранее при помощи функции DdeCreateStringHandle.

В нашем приложении DDEMLCL для создания канала с сервером используется следующий фрагмент кода:

Идентификатор канала, полученный от функции DdeConnect, следует сохранить для обеспечения возможности получения данных от сервера.

Что же происходит, когда клиент создает канал, вызывая функцию DdeConnect?

Прежде всего, библиотека DDEML посылает транзакцию с кодом XTYP_CONNECT всем активным серверам, которые зарегистрировали сервис, указанный во втором параметре функции DdeConnect.

Для транзакции XTYP_CONNECT параметры функции обратного вызова принимают следующие значения:

ПараметрЗначение
hsz1Идентификатор строки, содержащей имя раздела
hsz2Идентификатор строки, содержащей имя сервиса
dwData1Адрес структуры CONVCONTEXT
dwData2Если значение равно TRUE, данная копия приложения является одновременно и клиентом, и сервером. Если же значение равно FALSE, клиент и сервер являются разными приложениями или разными копиями приложения

Обработчик транзакции XTYP_CONNECT, расположенный в функции обратного вызова сервера, должен проверить сервис и раздел, идентификаторы которых переданы через параметры функции. Если сервер поддерживает этот сервис и раздел, можно создавать канал. В таком случае функция обратного вызова должна вернуть значение TRUE. Иначе следует вернуть FALSE.

Приведенный ниже фрагмент кода, взятый из нашего приложения DDEMLSR, проверяет только сервис (так как в нашем приложении определен только один сервис и один раздел):

Заметим, что мы сравниваем не строки, содержащие имя сервиса, а идентификаторы, так как для одинаковых строк в данном случае будут созданы одинаковые идентификаторы.

В случае успешного создания канала сервер получает от системы DDEML транзакцию с кодом XTYP_CONNECT_CONFIRM. При обработке этой транзакции сервер может сохранить идентификатор созданного канала (который передается функции обратного вызова через параметр hConv) для дальнейшего использования.

Приведем назначение параметров функции обратного вызова для транзакции XTYP_CONNECT_CONFIRM:

ПараметрЗначение
hsz1Идентификатор строки, содержащей имя раздела
hsz2Идентификатор строки, содержащей имя сервиса
dwData2Если значение равно TRUE, данная копия приложения является одновременно и клиентом, и сервером. Если же значение равно FALSE, клиент и сервер являются разными приложениями или разными копиями приложения

Когда канал связи больше не нужен, клиент или сервер может уничтожить его, вызвав функцию DdeDisconnect:

В качестве единственного параметра этой функции передается идентификатор уничтожаемого канала.

В процессе удаления канала «партнер» приложения, выступившего инициатором удаления канала, получает транзакцию XTYP_DISCONNECT. Соответствующий обработчик может при необходимости выполнить действия по освобождению ресурсов, заказанных приложением для работы с данным каналом связи.

Приложение DDEMLSR обрабатывает транзакцию XTYP_DISCONNECT следующим образом:

3.3. Передача данных через канал DDEML

Итак, мы создали канал связи между сервером и клиентом. И сервер, и клиент получили и сохранили идентификаторы созданного канала связи. Теперь все готово для того чтобы приступить к передаче данных.

Передача и прием данных может выполняться в трех режимах: по явному запросу, через «теплый» канал, или через «горячий» канал.

В первом случае клиент посылает серверу запрос, указав нужный элемент данных. Сервер, получив такой запрос, предоставляет клиенту нужные данные. «Теплый» и «горячий» каналы связи создаются в тех случаях, когда клиент должен постоянно следить за изменениями данных, хранящихся в памяти сервера.

В «теплом» режиме при изменении данных сервер посылает клиенту соответствующее извещение. Получив такое извещение, клиент запрашивает у сервера новые данные.

В «горячем» режиме при изменении данных сервер самостоятельно посылает клиенту данные без дополнительного запроса.

Процесс передачи данных заключается в посылке транзакций. Отметим, что транзакции бывают синхронные и асинхронные.

Клиент, пославший синхронную транзакцию, дожидается ее завершения в течение заданного интервала времени. Если по истечении этого интервала времени транзакция не завершилась, клиент получает код ошибки.

После посылки асинхронной транзакции клиент не ждет завершения транзакции. Когда транзакция будет завершена, клиент получит от системы DDEML транзакцию XTYP_XACT_COMPLETE.

В наших примерах мы будем работать с синхронными транзакциями.

Запрос данных от сервера

Для того чтобы получить данные от сервера, клиент должен послать серверу транзакцию XTYP_REQUEST. Задача посылки серверу транзакции решается с помощью функции DdeClientTransaction:

Если приложение запрашивает данные у сервера, для первых двух параметров следует указать нулевые значения (так как клиент не передает данные серверу, а наоборот, запрашивает их).

Через параметр hConv следует передать идентификатор созданного ранее канала связи.

Так как по одному каналу связи можно передавать различные элементы данных, следует указать нужный элемент данных с помощью параметра hszItem.

Формат данных передается через параметр uFmt. Здесь вы можете использовать один из идентификаторов формата Clipboard, такой как CF_TEXT или CF_BITMAP, в зависимости от того, что собой представляют передаваемые данные.

Через параметр uType следует передать код транзакции, посылаемой серверу. Для запроса данных следует послать транзакцию XTYP_REQUEST.

Параметр dwTimeout задает для синхронных транзакций время ожидания завершения транзакции (в миллисекундах). Вы можете указать для этого параметра значение TIMEOUT_ASYNC, в этом случае будет запущена асинхронная транзакция.

Параметр pdwResult должен содержать указатель на двойное слово. В это слово будет записан код результата выполнения транзакции. Если проверка не используется, через этот параметр можно передать нулевое значение.

Приведем фрагмент кода приложения DDEMLCL, в котором выполняется запрос данных от сервера:

В случае успешного завершения транзакции XTYP_REQUEST функция DdeClientTransaction возвращает идентификатор области глобальной памяти, в которой расположены полученные данные.

Приложение должно переписать эти данные в свой буфер, вызвав для этого функцию DdeGetData:

Последний параметр указывает смещение внутри области глобальной памяти, начиная с которого выполняется копирование. В нашем примере смещение равно нулю.

Теперь посмотрим на сервер. Получив от клиента транзакцию XTYP_REQUEST, он должен передать данные клиенту.

Приведем назначение параметров функции обратного вызова (сторона сервера) для транзакции XTYP_REQUEST:

ПараметрЗначение
hsz1Идентификатор строки, содержащей имя раздела
hsz2Идентификатор строки, содержащей имя сервиса

Возможный вариант обработчика транзакции XTYP_REQUEST показан в следующем фрагменте кода, взятом из нашего приложения DDEMLSR:

Этот фрагмент передает клиенту текстовую строку szDDEServerVersion.

Однако вначале сервер должен заказать блок глобальной памяти, записав туда передаваемые данные. Это необходимо сделать при помощи функции DdeCreateDataHandle:

Если с помощью функции DdeCreateDataHandle вы заказываете блок памяти, идентификатор которого будет возвращен функцией обратного вызова, последний параметр следует указать как NULL. В этом случае система DDEML освободит блок памяти самостоятельно, как только в нем отпадет потребность.

Итак, при обработке транзакции XTYP_REQUEST функция обратного вызова сервера создала блок глобальной памяти и записала туда передаваемые данные. Затем она должна возвратить идентификатор созданного блока памяти или NULL, если блок памяти создать невозможно.

Передача данных серверу

Процедура передачи данных состоит из двух шагов. Вначале надо создать блок глобальной памяти и записать в него передаваемые данные. Для этого следует воспользоваться только что рассмотренной нами функцией DdeCreateDataHandle:

Затем клиент должен передать серверу транзакцию XTYP_POKE, вызвав для этого функцию DdeClientTransaction:

Приведем описание параметров для транзакции XTYP_POKE:

ПараметрЗначение
hsz1Идентификатор строки, содержащей имя раздела
hsz2Идентификатор строки, содержащей имя сервиса
hDataИдентификатор данных, передаваемых серверу

Обработчик транзакции XTYP_POKE в приложении DDEMLSR выглядит следующим образом:

Этот обработчик сначала проверяет идентификатор элемента данных, затем получает данные с помощью рассмотренной нами ранее функции DdeGetData. Полученные данные отображаются на экране при помощи функции MessageBox.

Обратите внимание, что в качестве признака успешного завершения транзакции возвращается значение DDE_FACK, определенное в файле ddeml.h.

Выполнение команды

Помимо передачи данных возможно такое взаимодействие между клиентом и сервером, когда клиент передает серверу команды в виде текстовой строки, а сервер их исполняет. Вообще говоря, этот механизм можно реализовать с помощью рассмотренных нами ранее транзакций XTYP_POKE и XTYP_REQUEST, однако существует специально предназначенная для передачи команд транзакция XTYP_EXECUTE. Вот соответствующие параметры, передаваемые функции обратного вызова:

ПараметрЗначение
hsz1Идентификатор строки, содержащей имя раздела
hsz2Идентификатор строки, содержащей имя сервиса

Процесс передачи команды очень напоминает процесс передачи данных серверу через транзакцию XTYP_POKE.

Вначале необходимо при помощи функции DdeCreateDataHandle создать блок памяти, содержащей текстовую строку команды. Отличие заключается в том, что параметр hszItem должен быть указан как NULL:

Затем с помощью функции DdeClientTransaction серверу посылается транзакция XTYP_EXECUTE:

Для того чтобы получить доступ к командной строке, обработчик транзакции XTYP_EXECUTE, расположенный в функции обратного вызова сервера, должен использовать функцию DdeAccessData:

Эта функция возвращает указатель на начало области памяти, содержащей команду.

После успешного выполнения команды функция обратного вызова сервера должна вернуть значение DDE_FACK. Если команда не поддерживается, нужно вернуть значение DDE_FNOTPROCESSED. В том случае, когда сервер может выполнить команду позже (потому что занят, например, выполнением другой команды), функция обратного вызова должна вернуть значение DDE_FBUSY.

Клиент может проверить результат выполнения передачи команды, если проанализирует содержимое двойного слова, на которое указывал параметр lpdwResult перед вызовом функции DdeClientTransaction. Например, если в этом слове установлен бит DDE_FBUSY, можно попробовать повторить посылку команды позже.

3.4. Приложение DDEMLSR

Приложение DDEMLSR (рис. 3.5) регистрирует сервис «BMPServer». Клиент может установить канал связи с разделом «BMPFile» и работать с элементом данных «DDEData».

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.5. Приложение DDEMLSR

Функции, выполняемые сервером, предельно просты.

Когда сервер получает запрос на передачу данных клиенту, он в ответ передает текстовую строку, в которой находится описание версии приложения DDEMLSR.

Если клиент посылает серверу данные (в виде текстовой строки), сервер отображает данные на экране при помощи функции MessageBox (рис. 3.6).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.6. Сервер отображает текстовую строку, полученную от клиента по каналу DDE

Функция WinMain и функция главного окна приложения определены в файле ddemlsr.cpp (листинг 3.1).

Листинг 3.1. Файл ddeml/ddemlsr.cpp

Для того чтобы скрыть главное окно приложения (а точнее, не показывать его вовсе), достаточно убрать вызов функции ShowWindow перед запуском цикла обработки сообщений. Разумеется, для стиля окна в этом случае не следует использовать значение WS_VISIBLE.

При создании главного окна приложения обработчик сообщения WM_CREATE инициализирует сервер, вызывая функцию DDEServerOpen, определенную в файле ddemlfn.cpp (листинг 3.2). Функции передается имена сервиса, раздела данных и элемента данных.

Обработчики сообщений от меню предназначены для просмотра версии сервера и завершения работы приложения. Эти действия выполняются обычным образом.

При завершении работы приложения обработчик сообщения WM_DESTROY закрывает канал DDEML и освобождает все занятые ресурсы, вызывая функцию DDEServerClose, определенную в файле ddemlfn.cpp.

Для удобства мы собрали все функции, имеющие отношение к DDEML, в файле ddemlfn.cpp. Там же определена и функция обратного вызова для сервера DDEML.

Листинг 3.2. Файл ddeml/ddemlfn.cpp

Транзакция XTYP_ERROR передается в функцию обратного вызова в случае возникновения ошибки. Младшее слово параметра dwData1 содержит код ошибки.

Файл ddemlsr.hpp (листинг 3.3) содержит определения констант для приложения DDEMLSR.

Листинг 3.3. Файл ddeml/ddemlsr.hpp

В файле определения ресурсов (листинг 3.4) описано главное меню приложения и пиктограмма.

Листинг 3.4. Файл ddeml/ddemlsr.rc

Файл определения модуля приложения DDEMLSR приведен в листинге 3.5.

Листинг 3.5. Файл ddeml/ddemlsr.def

3.5. Приложение DDEMLCL

Приложение DDEMLCL создано нами специально для работы с сервером DDEMLSR, описанном в предыдущем разделе. Вы можете запустить сервер перед запуском клиента DDEMLCL, либо не делать этого. В последнем случае на экране появится предупреждающее сообщение о том, что сервер не запущен (рис. 3.7).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.7. Запрос на запуск сервера DDEML

Вам будет предложено запустить сервер, для чего следует нажать на клавишу «Yes». Приложение DDEMLCL предпримет попытку запустить приложение DDEMLSR из текущего каталога или из каталогов, указанных в переменной среды PATH операционной системы MS-DOS.

Главное окно приложения представлено на рис. 3.8.

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.8. Приложение DDEMLCL

С помощью меню «Action» вы можете послать серверу текстовую строку «c:\\nicebmp\\sky.bmp» (строка «Send Filename») или запросить версию сервера (строка «Get Server Version»). В последнем случае принятая строка будет отображена на экране (рис. 3.9).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.9. Клиент отображает текстовую строку, полученную от сервера

Функция WinMain и функция главного окна приложения DDEMLCL определены в файле ddemlcl.cpp (листинг 3.6).

Листинг 3.6. Файл ddeml/ddemlcl.cpp

Обработчик сообщения WM_CREATE при инициализации главного окна приложения вызывает функцию DDEClientOpen, определенную в файле ddemlcf.cpp (листинг 3.7). Эта функция регистрирует приложение в библиотеке DDEML и пытается создать канал связи с сервером.

Если канал связи создать не удалось, приложение DDEMLCL делает вывод о том, что сервер не запущен, и предлагает пользователю запустить его. Запуск выполняется при помощи функции WinExec. После удачного запуска сервера делается еще одна попытка создать канал связи.

Когда пользователь выбирает из меню «Action» строку «Send Filename», приложение вызывает функцию DDESend, определенную в файле ddemlcf.cpp. Этой функции передается идентификатор созданного канала связи и текстовая строка «c:\\nicebmp\\sky.bmp». Функция DDESend передаст строку серверу, который отобразит ее на экране.

Если пользователь выбирает из меню «Action» строку «Get Server Version», вызывается функция DDEReceive, также определенная в файле ddemlcf.cpp. Этой функции помимо идентификатора канала связи передается адрес и размер буфера, в который нужно записать принятую информацию. После приема данные отображаются на экране в виде текстовой строки с помощью функции MessageBox.

Когда приложение DDEMLCL завершает свою работу, вызывается функция DDEClientClose, закрывающая канал и освобождающая связанные с ним ресурсы.

В файле ddemlcf.cpp (листинг 3.7) собраны все функции, имеющие отношение к DDEML.

Листинг 3.7. Файл ddeml/ddemlcf.cpp

Все символические константы определены в файле ddemlcf.hpp (листинг 3.8).

Листинг 3.8. Файл ddeml/ddemlcf.hpp

Файл описания ресурсов представлен в листинге 3.9.

Листинг 3.9. Файл ddeml/ddemlcf.rc

Файл определения модуля для приложения DDEMLCL вы найдете в листинге 3.10.

Листинг 3.10. Файл ddeml/ddemlcf.def

3.6. Отладка DDEML-приложений

Библиотека DDEML позволяет создавать приложения, предназначенные для отладки DDEML-приложений. В частности, такие приложения могут перехватывать вызовы функций обратного вызова DDEML (как для сервера, так и для клиента), следить за использованием идентификаторов строк и данных, за регистрацией сервиса и так далее. Из-за ограниченного объема книги мы не сможем рассказать вам о том, как создавать такие приложения, однако вся необходимая информация есть в документации, которая входит в состав Microsoft SDK for Windows 3.1.

Тем не менее, мы научим вас пользоваться готовым приложением DDESpy, которое поставляется в составе SDK и специально предназначено для отладки DDEML-приложений.

Запустите приложение DDESpy и раскройте меню «Output» (рис. 3.10).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.10. Меню «Output» приложения DDESpy

С помощью этого меню вы можете направить поток отладочной информации в файл (строка «File. «), на отладочный терминал (строка «Debug Terminal» или в окно приложения DDESpy (строка «Screen»). Кроме того, с помощью строки «Clear Screen» вы можете очистить содержимое окна приложения DDESpy от отладочной информации (если она там есть).

В меню «Output» вам надо выбрать строку «File. » и с помощью появившейся на экране диалоговой панели задать путь к файлу, в который будет записана отладочная информация.

Затем раскройте меню «Monitor» (рис. 3.11).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.11. Меню «Monitor» приложения DDESpy

С помощью этого меню вы можете определить состав отладочной информации, отображаемой в окне приложения и сохраняемой в только что указанном вами файле. Отметьте все строки, как на рис. 3.11. Теперь вы сможете получить полную отладочную информацию.

Затем раскройте меню «Track» (рис. 3.12).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.12. Меню «Track» приложения DDESpy

С помощью этого меню вы сможете задать информацию о системе DDEML, отображаемую в отдельных окнах.

Отметьте все строки в меню «Track». При этом в нижней части экрана монитора появится несколько новых пиктограмм, соответствующих отдельным окнам.

Теперь все готово к отладке.

Запустите приложение DDEMLSR, описанное нами раньше. В главном окне приложения DDESpy появятся текстовые строки описания происходящих событий. Эти строки одновременно записываются в файл, указанный нами ранее. Мы к ним еще вернемся, а пока давайте раскроем пиктограмму «Registered Service». Появится окно, в котором вы сможете увидеть имя сервиса «BMPServer», а также название и идентификатор копии приложения (рис. 3.13).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.13. Список серверов DDEML

Раскройте окно «Active Conversation», в котором отображается информация об активных каналах связи.

В этот момент времени ни один канал связи еще не создан, поэтому окно пустое. Запустите приложение DDEMLCL, предназначенное для совместной работы с приложением DDEMLSR. Оно создаст канал связи, используя сервис «BMPServer» и раздел «BMPFile». Теперь в окне «Active Conversation» есть информация о сервисе, разделе и идентификаторах копий приложений клиента и сервера, создавшего канал связи (рис. 3.14).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.14. Список активных каналов

Итак, канал связи установлен. Раскройте окно «String Handles», отображающее список созданных идентификаторов строк (рис. 3.15).

Что такое dde сервер. Смотреть фото Что такое dde сервер. Смотреть картинку Что такое dde сервер. Картинка про Что такое dde сервер. Фото Что такое dde сервер

Рис. 3.15. Список идентификаторов строк

Сделайте активным окно клиента DDEMLCL и выполните пересылку данных, выбрав из меню «Action» строки «Send Filename» и затем «Get Server Version». Будет выполнена передача данных по каналу связи, причем информация о результате будет записана в отладочный файл.

Закройте приложение DDEMLCL и сделайте активным окно «String Handles». Теперь счетчик использования всех трех идентификаторов строк будет равен 1, так как клиент освободил эти идентификаторы. Однако сервер продолжает их использовать, поэтому идентификаторы не уничтожаются.

Окно «Active Conversation» очистится, так как теперь в системе нет активных каналов связи (если только их не создали какие-либо другие приложения).

Теперь завершите приложение DDEMLSR. Окна «String Handles» и «Registered Service» теперь тоже очистятся, так как все строки уничтожены, а сервис больше не доступен.

Завершите приложение DDESpy и загрузите в любой текстовый редактор файл, содержащий протокол отладки. Мы приведем фрагменты такого файла, полученного в результате выполнения описанных выше манипуляций с приложениями DDEMLSR и DDEMLCL.

Первые три строки появились в результате запуска сервера DDEMLSR. Они содержат сведения о том, что были созданы три идентификатора строк для копии приложения с идентификатором 0x458f. Указано время события (от момента запуска Windows), идентификаторы созданных строк (c0d0, c0d5, c2d8) и содержимое строк.

Далее идут строки, описывающие вызов функции обратного вызова сервера:

Здесь функция обратного вызова была вызвана для выполнения регистрации сервиса «BMPServer». Вы можете определить содержимое всех параметров функции на момент вызова.

В следующем фрагмента отражен факт посылки данных серверу:

Следом идет обращение к функции обратного вызова:

А вот запрос данных от сервера:

В следующем фрагменте листинга выполняется запрос на уничтожение канала связи, после чего управление получает функция обратного вызова:

Перед завершением работы сервер должен сообщить системе DDEML, что обеспечиваемый им сервис больше не доступен. Следующий фрагмент листинга отражает процедуру «изъятия» сервиса :

Анализируя содержимое протокола отладки, вы можете проследить за тем, чтобы при завершении сервера освобождались все занимаемые им ресурсы, такие как идентификаторы строк и сервис. Вы можете проверить значения параметров функции обратного вызова для всех или отдельных транзакций, проследить формат передаваемых данных и многое другое.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *