на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Обмен данными в Windows
p align="left">Внимание! в документации по Windows 3.x SDK и Win32 SDK содержалась ошибка -- там были перепутаны пояснения к полям fResponse и fAckReq, так что описание структуры DDEDATA противоречило описанию сообщения WM_DDE_DATA. В документации, сопровождающей компилятор Microsoft Visual C++ v4.0 эта ошибка была исправлена.

Заметьте, что сервер может потребовать подтверждения о приеме посланных данных. Для этого он устанавливает бит fAckReq в заголовке переданных данных равным 1. В таком случае необходимо послать ответное сообщение WM_DDE_ACK (положительное или отрицательное, если возникла какая-либо ошибка).

Если сервер не имеет нужных данных, то вместо WM_DDE_DATA клиент получит WM_DDE_ACK (отрицательное)

WM_DDE_ACK hWnd aItem & wStatus (Packed Win32)

Младший компонент lParam содержит информацию о посылаемом подтверждении. Младший байт этого слова содержит код, возвращаемый приложением, старший байт содержит два значащих бита 0x80 и 0x40. Часто этот параметр представляется в виде структуры DDEACK. Старшее слово lParam представляет собой атом, идентифицирующий данные. Согласно документации этот атом обязательно должен быть удален при обработке этого сообщения. В случае платформы Win32 параметр lParam используется для передачи “упакованного” значения; при этом надо помнить, что если WM_DDE_ACK приходит в ответ на WM_DDE_INITIATE, то параметр lParam содержит обычные, не упакованные данные.

Структура DDEACK содержит следующие данные:

typedef struct tagDDEACK { WORD bAppReturnCode:8, // код, определяемый приложением reserved:6, fBusy:1, // 1 -- сервер занят и не может обработать запрос fAck:1; // 1 -- сообщение было получено приложением } DDEACK;

В зависимости от значений битов fBusy и fAck различают следующие возможные виды ответов:

fAck = 1 fBusy = 0 -- положительное подтверждение

fAck = 0 fBusy = 0 -- отрицательное подтверждение

fAck = 0 fBusy = 1 -- сервер занят, либо не может обработать запрос в разумные сроки (что есть “разумные” сроки -- не поясняется)

Согласно документации установка обеих флагов fAck и fBusy одновременно должна быть исключена.

Вместо структуры DDEACK часто используют просто битовые шаблоны -- 0x8000 соответствует положительному подтверждению, 0 -- отрицательному и 0x4000 -- сервер занят (вообще говоря, это тоже отрицательное подтверждение, хотя запрос можно попробовать повторить).

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

// // wait for time out // static BOOL TimeOut( HWND hWnd, UINT wMsg, UINT uTimeOut ) { DWORD dwTime; MSG msg;

// FALSE design normal termination // TRUE design time-out or negative WM_DDE_ACK dwTime= GetCurrentTime(); while ( dwTime + uTimeOut > GetCurrentTime() ) { if ( PeekMessage( &msg, hWnd, NULL, NULL, PM_REMOVE ) ) { // обработать полученное сообщение TranslateMessage( &msg ); DispatchMessage( &msg ); if ( msg.message == WM_DDE_ACK ) { // check for .fAck return LOWORD( msg.lParam ) & 0x8000 ? FALSE : TRUE; } else if ( msg.message == wMsg ) return FALSE; } }

return TRUE; }

Обычно процедура, ожидающая нужное сообщение, выглядит несколько иначе. Это связано с желательным отображением курсора ожидания (в виде песочных часов), а также с обработкой сообщений, извлеченных из очереди. Во многих случаях нормальная обработка сообщений не сводится только к функциям TranslateMessage и DispatchMessage, но также включает поддержку акселераторов, немодальных диалогов и пр. Помимо этого следует учесть, что в случае платформы Windows 3.x размер очереди сообщений приложения сравнительно невелик -- так что при извлечении сообщений, направленных только конкретному окну, очередь может легко переполниться.

Еще одно замечание касается времени ожидания ответа от сервера. Этот промежуток не надо назначать очень большим, но в то же время он должен быть достаточным, что бы даже на медленных машинах уверенно получать ответ от сервера. При избыточно большом времени ожидания ответа может возникать впечатление “зависания” приложения, пока оно ждет ответа. Обычно человек ожидает от компьютера почти мгновенной реакции или, в худшем случае, явно видимой работы. Если программа останавливается на срок более 10-15 секунд, то уже возникает беспокойство о ее работе.

Практически приемлемым является интервал порядка 5-30 секунд, так как на средней машине ответ может задерживаться до 5-10 секунд при нормальной работе и, соответственно, на медленных машинах интервал следует увеличить примерно до тридцати секунд. (Различие между быстрыми и медленными машинами весьма относительно -- с ростом мощности компьютеров растет нагрузка на них, поэтому время выполнения более-менее значительных операций снижается сравнительно медленно). Возможным решением является двухэтапное ожидание -- первый этап до 3-6 секунд проходит как обычно, а по истечении этого интервала отображается окно диалога с кнопкой “Cancel”, после чего ожидание продолжается либо до получения ответа, либо до отмены ожидания пользователем. Это позволяет пользователю оценить занятость системы и, при необходимости, продолжить ожидание в разумных пределах.

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

· если функция PostMessage не может послать сообщение, объекты можно удалять сразу, так как второе приложение их не получит.

· если сообщение послано, то момент уничтожения объектов выбирается в соответствии с описанием сообщения в документации. Так, например, атомы обычно удаляются по следующей схеме

- при получении посланного запроса проверяется необходимость ответа, если ответ нужен, то атом передается вместе с ответом и уничтожается приложением, пославшим запрос

- если ответ нужен, но его послать не удается, то атом уничтожается получившим запрос приложением

- если ответ не нужен, то атом опять-же уничтожается получившим запрос приложением

· посланное сообщение может “не дойти” до адресата (например, если окно-получатель будет закрыто уже после того, как к нему в очередь попадет это сообщение, но до его обработки). При этом ответа не будет, а приложение-получатель освободить ресурсы не сможет.

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

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

“Горячая” связь -- hot link

Протокол при горячей связи. После инициации обмена клиент посылает запрос WM_DDE_ADVISE, указывая желаемые данные. Сервер отвечает о возможности горячей связи, и, обычно, сразу же посылает первые данные, для инициации клиента. Таким образом осуществялется как-бы “подписка” на получение необходимых данных при их изменении. Этот вид связи удобен, если Вам необходимо взаимодействовать с какой-либо базой данных, содержимое которой может динамически обновляться, как например база данных “товары на складе” для больших магазинов -- доступ к этой базе одновременно могут иметь разные отделы магазина и список товаров, имеющихся на сладе, постоянно изменяется. Использование горячей связи в этом случае позволит создать локальные списки на компьютерах разных отделов и автоматически обновлять их, как только осуществляется изменение общей базы данных.

WM_DDE_ADVISE hWnd aItem & hOptions (Packed Win32)

Младший компонент параметра lParam содержит хендл глобального разделяемого блока, содержащего небольшую структуру DDEADVISE, а старший компонент -- атом, описывающий данные на которые осуществляется подписка. Структура DDEADVISE определяет тип связи -- горячая или холодная, а также необходимость требовать подтверждения о доставке данных от клиента. В случае платформы Win32 параметр lParam используется для передачи “упакованного” значения. Сервер, получивший это сообщение обязан ответить на него посылкой подтверждения WM_DDE_ACK, положительного или отрицательного. Освобождение ресурсов: Клиент, пославший запрос, должен дождаться ответа от сервера. Если ответ положительный, то блок данных должен быть удален сервером, а если отрицательный, то клиент должен сам его удалить.

Структура DDEADVISE содержит следующие данные:

typedef struct { WORD reserved:14, fDeferUpd:1, // 1-”теплая” связь, 0-”горячая” fAckReq:1; // 1-необходимо требовать подтверждение, 0-не надо short cfFormat; // желаемый формат данных } DDEADVISE;

При задании бита fDeferUpd равным 1 осуществляется так называемая теплая связь, при которой сервер только информирует о наличии у него измененных данных, но не посылает их клиенту непосредственно. В случае горячей связи этот бит должет быть равен 0. Бит fAckReq, равный 1, указывает на необходимость требовать от клиента подтверждения о получении данных. Позже, когда сервер начнет посылать клиенту сообщения WM_DDE_DATA он установит в структуре DDEDATA бит fAckReq соответствующим тому, который Вы указали в структуре DDEACK и, соответственно, клиент должен будет подтверждать получение им данных от сервера (надо учесть, что бит fAckReq влияет на стратегию освобождения посылаемых данных -- подробнее см. описание сообщения WM_DDE_DATA).

Поле cfFormat указывает на формат данных, которые клиент ожидает от сервера. Вы можете для одного вида данных в пределах одного DDE-разговора подписаться на получение данных разного типа одновременно, посылая WM_DDE_ADVISE столько раз, сколько форматов данных Вы хотите получать. Однако такая возможность разрешена только для горячей связи. Согласно документации подписка на одни и те-же данные в разных форматах для теплой связи запрещена.

Сервер, при получении сообщения WM_DDE_ADVISE, проверяет возможность осуществить подписку на эти данные, создает необходимые ему структуры данных и отвечает клиенту сообщением WM_DDE_ACK -- положительным или отрицательным. Это сообщение в данном случае используется так-же, как и при ответе на WM_DDE_DATA.

Если подписка осуществлена успешно, то далее сервер начинает извещать клиента об обновлении данных, осуществляя каждый раз пересылку этих данных клиенту с помощью уже рассмотренного сообщения WM_DDE_DATA. Единственное отличие от получения данных в ответ на WM_DDE_REQUEST заключается в том, что бит fResponse структуры DDEDATA равен 0, тогда как при отправке данных по запросу он устанавливается в 1. Это позволяет определить причину получения данных при обработке сообщения.

Заканчивается такой обмен посылкой WM_DDE_UNADVISE серверу. В этом сообщении указывается, от подписки на какие данные клиент отказывается (так как теоретически один клиент может подписаться сразу на несколько видов данных).

WM_DDE_UNADVISE hWnd aItem & cfFormat

Младшее слово параметра lParam описывает формат данных, а старшее слово -- атом, описывающий данные на которые осуществляется подписка. В случае платформы Win32 параметр lParam используется также, как и в случае Windows 3.x. Если параметр cfFormat равен 0, то отменяется подписка на указанные данные для всех тех форматов, для которых была осуществлена подписка. Если параметр aItem равен NULL, то отменяется подписка на все виды данных в пределах данного DDE-разговора. Сервер, обработав это сообщение, должен послать в ответ подтверждение WM_DDE_ACK, положительное или отрицательное; при этом если одна операция отменяет подписку на данные в разных форматах, то посылается только одно подтверждение.

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



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