Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_II.pdf
Скачиваний:
41
Добавлен:
05.06.2014
Размер:
3.02 Mб
Скачать

144

Инициирование диалога DDE

Впрограмме SHOWPOP1 диалог инициируется после вызова в WinMain функции UpdateWindow путем отправки из WndProc асинхронного, определяемого пользователем сообщения WM_USER_INITIATE. Как правило клиент инициирует диалог с помощью команды меню.

Вответ на это, определяемое пользователем сообщение, WndProc вызывает функцию GlobalAddAtom для создания атомов для имени приложения сервера ("DdePop1") и имени раздела ("US_Population"). WndProc посылает широковещательное асинхронное сообщение WM_DDE_INITIATE с помощью вызова функции SendMessage с

описателем окна HWND_BROADCAST.

Как мы знаем, сервер, который ищет совпадения атомов приложения и раздела, должен отправить клиенту ответное асинхронное сообщение WM_DDE_ACK. Поскольку это сообщение асинхронное, то есть оно посылается функцией SendMessage, а не PostMessage, то клиент получит сообщение WM_DDE_ACK раньше, чем завершится исходный вызов функции SendMessage для посылки сообщения WM_DDE_INITIATE. WndProc обрабатывает сообщение WM_DDE_ACK, сохраняя описатель окна сервера в переменной hwndServer, и удаляя атомы, сопутствующие сообщению.

Если клиент рассылает широковещательное сообщение WM_DDE_INITIATE с именами приложения и раздела равными NULL, он должен быть готов к получению нескольких сообщений WM_DDE_ACK от каждого сервера, который может удовлетворить его запрос. В этом случае клиент должен решить, услугами какого сервера ему воспользоваться. Остальным нужно отправить синхронные сообщения WM_DDE_TERMINATE для завершения диалога.

Возможна ситуация, когда hwndServer будет равным NULL и после вызова функции SendMessage для посылки сообщения WM_DDE_INITIATE. Это означает, что программа DDEPOP1 не запущена в системе. В этом случае WndProc пытается запустить программу DDEPOP1, используя для этого вызов функции WinExec. Вызов функции WinExec для загрузки программы DDEPOP1 ищет ее в текущем каталоге и в каталогах, указанных в переменной окружения PATH. Затем WndProc снова рассылает асинхронное сообщение WM_DDE_INITIATE. Если hwndServer по-прежнему равен NULL, то WndProc выводит на экран окно сообщений, извещающее пользователя о наличии ошибки.

Далее, для каждого штата, из перечисленных в структуре pop, WndProc с помощью вызова функции GlobalAlloc выделяет структуру DDEADVISE. Флагу fAckReq присваивается значение TRUE (означающее, что сервер должен послать синхронное сообщение WM_DDE_DATA с полем fAckReq структуры DDEDATA равным NULL). Флагу fDeferUpd ("отсроченное обновление — deferred update") присваивается значение FALSE (означающее не теплую связь, а горячую), и полю cfFormat присваивается значение CF_TEXT. Функция GlobalAddAtom добавляет атом для двухбуквенной аббревиатуры штата.

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

Вполне вероятно, что за сообщением WM_DDE_ACK от сервера последует сообщение WM_DDE_DATA для элемента данных. По этой причине, программа SHOWPOP1 вызывает функцию PeekMessage и функцию DispatchMessage для извлечения сообщений DDE из очереди сообщений и передачи их в WndProc.

Сообщение WM_DDE_DATA

Следом за сообщениями WM_DDE_ADVISE WndProc будет получать от сервера сообщения WM_DDE_DATA, содержащие обновленные данные о населении. Как ранее отмечалось, lParam является объектом памяти, в котором находятся описатель блока памяти со структурой DDEDATA и атом, идентифицирующий элемент данных. Эта информация извлекается из сообщения функцией UnpackDDElParam.

Программа SHOWPOP1 проверяет, равно ли поле cfFormat структуры DDEDATA значению CF_TEXT. (Нам конечно известно, что в программе DDEPOP1 используется только формат CF_TEXT, но для завершенности программы такая проверка необходима.) Затем с помощью функции GlobalGetAtomName она получает текстовую строку, соответствующую атому элемента. Эта текстовая строка представляет собой двухбуквенную аббревиатуру штата.

Используя цикл for программа SHOWPOP1 просматривает список штатов в поисках совпадения. Если таковое обнаруживается, она копирует данные о населении из структуры DDEDATA в массив szPopulation, преобразуя его в длинное целое с помощью функции языка С atol, сохраняет его в структуре pop и делает окно недействительным.

Теперь осталось только освободить захваченные ресурсы. Если от клиента требуется подтверждение сообщения WM_DDE_DATA, WndProc его посылает. Если подтверждения не требуется (или вызов функции PostMessage

Соседние файлы в предмете Операционные системы