на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Обмен данными в Windows
p align="left">Когда Вы запускаете свою программу просмотра, она регистрируется в качестве программы просмотра буфера обмена с помощью функции

HWND SetClipboardViewer( hWnd );

при этом он становится на первое место в цепочке, а функция SetClipboardViewer возвращает хендл следующего за ним (или 0, если других программ (окон) просмотра нет). Этот хендл должен быть сохранен.

Далее, при обновлении данных в буфере обмена, Ваше окно получает сообщение WM_DRAWCLIPBOARD. Обычная обработка этого сообщения:

case WM_DRAWCLIPBOARD: if ( hWndNextViewer ) PostMessage( hWndNextViewer, wMsg, wParam, lParam ); InvalidateRect( hWnd, NULL, TRUE ); return 0;

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

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

BOOL ChangeClipboardChain( hWndViewer, hWndNextViewer );

Что значит: вместо окна hWndViewer будет использоваться окно hWndNextViewer. Эта функция обычно вызывается при обработке сообщения WM_DESTROY. В результате выполнения этой функции первая программа просмотра в цепочке получит сообщение (WM_CHANGECBCHAIN, hWndRemoved, hWndNext). Это сообщение обрабатывается так:

case WM_CHANGECBCHAIN: if ( wParam == hWndNextViewer ) { hWndNextViewer= LOWORD( lParam ); } else if ( hWndNextViewer ) { PostMessage( hWndNextViewer, wMsg, wParam, lParam ); } return 0;

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

Отображение данных программой просмотра происходит также, как и их обычное чтение (открыл-прочитал-закрыл).

Динамический обмен данными (DDE)

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

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

DDE основан на использовании сообщений для передачи данных между двумя приложениями. При этом одно из приложений (обычно содержащее данные) называется сервером (server), а другое (обычно требующее данных) - клиентом (client). В более общем виде: клиент выступает в роли активного приложения, требующего, что бы его запросы были обслужены сервером. Сам процесс обмена данными средствами DDE между клиентом и сервером называется DDE-разговором (DDE-conversation).

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

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

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

клиент посылает запрос(ы) серверу для выполнения требований.

в некоторых случаях сервер может информировать клиента об изменении или наличии тех или иных данных. Для этого клиент должен подписаться (advise) на необходимые данные.

обмен между клиентом и сервером может продолжаться до тех пор, пока один из них не потребует прекращения.

В процессе DDE-разговора происходит обмен сообщениями между двумя приложениями. Понятно, что адресатами таких сообщений являются не сами приложения, а их окна. В большинстве случаев для нормального ведения DDE-разговора создаются специальные скрытые (невидимые) окна, которые и осуществляют обмен сообщениями между собой. Конечно, в DDE могут участвовать окна одного приложения, не только разных, но надо учесть, что DDE для обмена данными в пределах одного приложения является неэффективным. Так как процессы подготовки и приема данных могут занимать значительное время, то требуется, чтобы для обмена сообщениями использовалась функция PostMessage, а не SendMessage (кроме установления DDE-разговора). Это, правда, создает дополнительную сложность -- необходимость синхронизации действий разных окон между собой.

В Windows содержится все необходимое для организации DDE, причем в двух экземплярах. Помимо старого способа, существующего с первых версий Windows, в Windows версии 3.1 была добавлена специальная библиотека DDEML (DDE Management Library), являющаяся “надстройкой” над старым способом и предназначенная для формализации протоколов обмена. Существенная разница между этими способами связана с тем, что для организации DDE старым способом вы должны предусмотреть обработку специальных сообщений необходимыми Вам окнами, а библиотека DDEML сама создает необходимые скрытые окна и организует обмен сообщениями; при этом для взаимодействия с Вашим приложением DDEML будет вызывать специально разработанную Вами CALLBACK процедуру (не являющую оконной процедурой).

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

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

Эта спецификация состоит из 3 пунктов:

имя приложения -- application (в DDEML называется сервис (service)); так как в большинстве случаев в документации применяется термин service, то его мы и будем использовать дальше. Хотя, надо отметить, этот параметр обычно задает условное имя приложения-сервера.

тему DDE-разговора -- topic

требуемые данные -- item

Имя сервиса и тема DDE-разговора используютсяпри установлении связи. В результате этого в системе должно быть установлен обмен данными между одной или несколькими парами окон, которые поддерживают данные сервис и тему. Одно из окон в каждой паре будет являться клиентом, а другое -- сервером. В процессе дальнейшего DDE-разговора может происходить обмен данными, имя которых задается отдельно и является возможным именем данных для данного сервиса и темы.

Эти три имени представлены в виде атомов (ATOM), поэтому нам надо разобраться с атомами и правилами их применения перед продолжением разговора о DDE.

Атомы

Атомами в Windows называются нумерованные строки текста, хранимые в специальной таблице. Максимальный размер строки 255 символов. При помещении строки в таблицу ей присваивается уникальный номер, который собственно и используется вместо самой строки. Часто атомом называют именно эти номера, а строки -- именами атомов. Обе платформы (Windows 3.x и Win32) используют для задания атомов 16-ти разрядные числа, называемые ATOM, что позволяет в одном двойном слове передавать до двух атомов.

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

Для каждого приложения доступны две таблицы атомов - локальная и глобальная. Так как DDE поддерживается между разными приложениями то, очевидно, должна применяться только глобальная таблица атомов.

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

ATOM GlobalAddAtom( lpszName ); UINT GlobalGetAtomName( aAtom, lpsBuffer, nMaxCount ); ATOM GlobalFindAtom( lpszName ); ATOM GlobalDeleteAtom( aAtom );

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

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

ATOM AddAtom( lpszName ); UINT GetAtomName( aAtom, lpsBuffer, nMaxCount ); ATOM FindAtom( lpszName ); ATOM DeleteAtom( aAtom );

BOOL InitAtomTable( UINT cTableEntries );

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

При обмене данными посредством DDE происходит последовательная посылка сообщений от одного приложения к другому и наоборот. Одна DDE транзакция обычно состоит из двух -- трех последовательных сообщений. В этих сообщениях часто передаются необходимые имена, представленные в виде глобальных атомов. При этом возникает необходимость так организовать обмен сообщениями, что бы обеспечить удаление всех вновь добавляемых атомов. Для этого принято такое решение: приложение, посылающее атомы вместе с сообщение должно эти атомы создать, а затем проверить код завершения функции PostMessage -- если посылка прошла успешно, то атом должен быть освобожден принимающим приложением, а если при посылке возникла ошибка, то атом должно удалить посылющее приложение. В некоторых случаях атом, полученный приложением с сообщением, может быть послан вместе с ответным сообщением назад (кроме сообщения WM_DDE_INITIATE, о чем см. ниже). В этом случае не обязательно атом удалять а потом создавать снова, можно использовать полученный; однако необходимо убедиться, что он был послан с ответным сообщением и, если посылка не состоялась, его надо удалить.

Особенности задания параметра lParam сообщений DDE

Следует учесть некоторые различия в применении параметра lParam сообщений DDE на 16-ти и 32-х разрядных платформах (Windows 3.x и Win32). Дело в том, что первоначально этот параметр использовался для передачи двух значений, часто атома имени данных и хендла глобального блока. В случае 32-х разрядной платформы хендл блока сам занимает двойное слово и разместиться в lParam совместно с атомом имени данных не может.

Для решения этой проблемы были введены специальные функции, осуществляющие “упаковку” двух указанных значений (называемых младшим и старшим) в одно двойное слово. Фактически можно считать, что выделяется специальная структура, содержащая пару полей, идентификатор которой используется в качестве lParam.

Так как разные сообщения DDE используют lParam различным образом, то и упаковка данных осуществляется не для каждого сообщения, так что для каждого сообщения надо проверять необходимость использования этого механизма, а для сообщения WM_DDE_ACK надо еще проверить, в ответ на какое сообщение он послан. Для работы с “упакованными” данными необходимо применять специальные функции:

LONG PackDDElParam( UINT uMsg, UINT uLow, UINT uHigh ); LONG UnpackDDElParam( UINT uMsg, LONG lParam, PUINT puLow, PUINT puHigh ); LONG FreeDDElParam( UINT uMsg, LONG lParam ); LONG ReuseDDElParam( LONG lParam, UINT uMsgIn, UINT uMsgOut, UINT uLow, UINT uHigh );

Функция PackDDElParam упаковывает указанные данные в промежуточную структуру, хендл которой возвращается в виде LONG; возвращаемое значение может быть использовано только для передачи данных с помощью функции PostMessage и только для некоторых сообщений DDE. Функция UnpackDDElParam выполняет обратную операцию, но промежуточная структура данных при этом сохраняется. Для того, что бы ее удалить необходимо использовать FreeDDElParam. Последняя функция ReuseDDElParam может применяться для использования одной структуры при повторной передаче данных или ответе на принятое сообщение. В качестве параметра lParam функции PostMessage необходимо указывать возвращаемое, а не первоначальное значение.

В описании параметров сообщений мы сохраняем прежний синтаксис, причем lParam может по-прежнему задаваться в виде двух компонент старший & младший. Единственное отличие, что под старшим и младшим компонентом не надо подразумевать слова, а для получения этих компонентом может потребоваться функция UnpackDDElParam, о чем в описании сообщения будет сделана специальная оговорка. В редких случаях могут даваться два описания параметров, для Windows 3.x и для Win32. Для различия этих вариантов в описании параметров сообщения могут быть добавлены специальные пояснения

(Packed Win32) -- если параметр упаковывается в случае платформы Win32

(Windows 3.x) -- если описание применяется только в случае Windows 3.x

(Win32) -- если описание применяется только в случае Win32

DDE, начало обмена и его завершение

Когда мы говорили об общем виде протокола DDE, мы отметили, что он основан на обмене сообщениями. В большинстве случаев сообщения посылаются (post) а не передаются (send). При этом приложение, посылающее сообщение не имеет возможности дождаться обработки этого сообщения. Поэтому те данные, которые посылаются одним приложением, должны быть уничтожены другим, что бы они не оставались в памяти. Единственное исключение из этого правила -- сообщения WM_DDE_INITIATE и ответ на него (WM_DDE_ACK) которые всегда передаются, а не посылаются.

Страницы: 1, 2, 3, 4, 5



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.