Листинг 2.4
Test - 12:
SendMessage(hWndA.WM_USER+l.(WPARAM)hWnd.O):
sprintf(s."0KHO Б.Режим %ї ",24/Test):
MessageBox(hWnd."Послали сообщение \п окну A",s,MB_T0PM0ST); В переменную Test было записано значение 12, чтобы в заголовке выводился текст Окно Б. Режим 2. Однако на рисунке можно увидеть надпись Окно Б. Режим 24.
При щелчке правой кнопкой на экране одновременно отображаются извещения об отправке и получении приложением А первого сообщения. Структура соответствующей функциональности довольно проста:
1. Функция PostMessageC) обращается к операционной системе, передает ей структуру, описывающую сообщение, и возвращает управление. Будет выполнен оператор, следующий в коде программы после функции PostMessageC), а на экран будет выведен текст Послали сообщение окну А.
2. Операционная система вызывает оконную функцию приложения А, которая выводит на экран текст Получено сообщение от окна Б.
3. Если при помощи кнопки ОК пользователь будет закрывать окна сообщения, то оконная процедура приложения А отправит ответ и на экране будут отображены еще два сообщения.
Чтобы понять причину неправильного формирования заголовка, нужно установить контрольный останов, как показано на рис. 2.3, и вывести на экран текущее значение переменной Test. В ней хранится единичное значение. Причина состоит в том, что оконная процедура приложения Б запустилась второй раз, но при этом не была еще завершена.
Обмен сообщениями
hWndA-FindUindow("MINIM","Окно А") ; if(hWndA) { Test-12;
I [Test »0x000000011
SendMessage(hUndA,UMJJSER+l,(UPARAM)hUnd,0); sprintf(з,"Окно Б.Режим Чі",24/Test); MessageBox(hWnd,"Послали сообщение \n окну А", з,
>
Рис. 2.3. Формирование текста заголовка Во время выполнения функции SendMessageO приложение А повторно вызывает оконную функцию приложения Б и первый же оператор оконной функции записывает в переменную Test единицу.
В данном простейшем примере установить ошибку и сделать программу реентерабельной довольно легко. Для этого нужно переменную Test сделать не глобальной, а локальной, то есть объявить внутри функции InputWndProcC). При этом переменная Test не будет искажаться, так как повторный запуск прерванной функции порождает в стеке новый экземпляр этой переменной.