КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Пример выполнения задания. Рассмотрим выполнение лабораторной работы на следующем примере. ⇐ ПредыдущаяСтр 6 из 6 Рассмотрим выполнение лабораторной работы на следующем примере. Задание. Получить и прокомментировать протокол сообщений, посылаемых окну редактора Notepad («Блокнот») при его закрытии. Окно закрывать щелчком по кнопке закрытия. Считать, что текст в окне редактора сохранен, т.е. запрос на сохранение выдаваться не будет. Пример выполнялся в системе Windows 7. Для других версий Windows поток сообщений может несколько отличаться. Сначала запустим Notepad, введем несколько строк текста и сохраним файл. Затем запустим Spy++ и выполним команду Spy+Log Messages. Откроется диалоговое окно Message Options. На вкладке Windows оттащим Finder Tool на окно Notepad. При этом можно обнаружить, что Notepad содержит, как минимум, два окна: основное окно программы и вложенное в него (дочернее) окно с панелью редактора. На самом деле, имеется еще окно строки состояния, которое может быть видимым или нет, в зависимости от настройки Notepad. Выберем главное окно, но включим переключатель Child Windows, чтобы получать сообщения для всех окон Notepad. На вкладке Messages для большей наглядности примера оставим все сообщения. Полезно перейти теперь в окно списка окон (через команду меню Spy++ Windows), на всякий случай обновить список (командой контекстного меню Refresh) и найти в списке окна Notepad. Это можно сделать либо просмотром всего списка, либо с помощью команды Search+Find Window. В нашем случае список содержит главное окно Notepad с хэндлом 0001056E, дочернее окно редактирования (хэндл 0001572) и дочернее окно строки состояния (00010574). Разумеется, значения хэндлов при других запусках Notepad могут быть другими. Выпишем значения хэндлов основного окна и дочерних окон, они могут пригодиться позднее, при анализе протокола сообщений. Вернемся в окно протокола сообщений. Там уже могли появиться записи в ходе выполнения команд Refresh и Find Window. Очистим протокол. Чтобы получить меньше ненужных сообщений, желательно расположить на экране окна таким образом, чтобы кнопка закрытия Notepad была как можно ближе к краю окна Spy++. Убедимся, что протоколирование включено (ненадолго поместим курсор на Notepad, при этом в окне Spy++ должен политься бурный поток сообщений). Удалим все сообщения командой Messages+Clear Log. Теперь за дело: быстро переведем курсор из окна Spy++ на кнопку закрытия Notepad и щелкнем левой кнопкой мыши. Дальше можно не спешить, поскольку после закрытия Notepad поток сообщений так или иначе прекратится. В данном случае в протокол успело попасть 166 сообщений. Сохраним их для редактирования в файле «Spy.txt». Полученный протокол приведен в таблице ниже.
Прокомментируем протокол. Строки 1-2. Курсор только что вошел в окно Notepad, и система запрашивает у этого окна, на какой части неклиентской области находится курсор. Окно отвечает: он в верхнем левом углу границы окна (HTTOPRIGHT). 3-4. Система предлагает окну сменить, если надо, форму курсора в соответствии с его положением (HTTOPRIGHT) и с последним сообщением, полученным от мыши (WM_MOUSEMOVE). Окно отвечает, что система ничего делать не должна (fHaltProcessing:True). Для данного положения курсора программа сама перерисовывает курсор в виде тонкой диагональной двунаправленной стрелки, показывающей, что можно изменить размер окна. 5. Асинхронное сообщение о перемещении мыши в неклиентской области. Чаще всего оно не обрабатывается прикладными программами. 6-7. У дочернего окна редактирования запрашивают позицию начала и конца выделенного в окне текста (например, чтобы отобразить его другими цветами). Ответ: 0, 0 (нет выделенного текста, курсор ввода расположен в начале текста). 8-9. Запрос номера строки, где начинается выделение. Ответ: 0. 10-11. Теперь запрашивается номер позиции в этой строке. Тоже 0. 12-13. Система снова запрашивает, где теперь находится курсор после перемещения мыши. Ответ: он на кнопке закрытия окна (HTCLOSE). Далее, в строках 14-79, многократно повторяется та же группа сообщений, что в строках 3-13, с двумя отличиями – небольшими изменениями позиции мыши (xPos, yPos) и другим ответом на WM_SETCURSOR: fHaltProcessing:False. Это система перепроверяет положение курсора, пока он ползет пару миллиметров по кнопке закрытия, и доверяет системе перерисовать курсор. По умолчанию на неклиентской области курсор изображается в виде стрелки. Трудно объяснить, почему в некоторых случаях система посылает сообщение WM_NCHITTEST 2-3 раза подряд, при неизменном положении курсора. Возможно, это зависит от скорости перемещения мыши. 80-81. Это уже интереснее. Система сообщает окну, что пользователь пытается его активизировать. И подробности: был щелчок левой кнопкой мыши на кнопке закрытия окна. Указывается также хэндл окна верхнего уровня, которое должно принимать решение, как реагировать на щелчок. Ответ: можно активизировать, окно не возражает; и, кроме того, щелчок надо передать кнопке закрытия для обработки (если бы ответ был MA_ACTIVATEANDEAT, окно бы активизировалось, но щелчок был бы «съеден», т.е. не привел бы к закрытию окна). Но пока что ни система, ни программа еще не уразумели, что надо закрывать окно. Выполняется обычная активизация окна, как если бы щелчок был сделан, например, на заголовке окна. 82-83. Окну сообщают, что его положение на экране будет изменено. Детали предстоящего изменения оконная функция может найти по указанному адресу (lpwp). Ответ не требуется, но сообщение принято к сведению. 84-85. Изменение положения окна завершено (в данном случае окно Notepad не сдвинулось по экрану, но разместилось поверх прочих окон Windows, а это считается «изменением Z-порядка»). 86-87. Окну сообщают, что программа Notepad активизируется. Параметр dwThreadID при этом должен указывать, какая нить владеет окном, теряющим активность. В данном случае – никакая. 88. Поскольку окно становится активным, ему сообщают, что неклиентская область требует перерисовки (другими цветами). 89-90. Система запрашивает у программы текст заголовка окна (потому что его надо отобразить заново на синем фоне). При этом cchTextMax – размер системного буфера для приема строки текста, а lpszText – адрес этого буфера. В ответ выдается 17 символов текста заголовка: «Spy.txt - Блокнот», и Spy++ отображает первую букву заголовка. 91. Ответ на WM_NCACTIVATE в строке 88: неклиентская часть перерисована. 92. Окно активизируется, при этом оно не находится в минимизированном состоянии. Никакое другое окно при этом не теряет активность. Сообщения 93-120 посылаются и обрабатываются в процессе обработки сообщения 92. 93-100. Сообщения IME. Обрабатываются только в версиях Windows, допускающих ввод иероглифов. 101-120. Идет малопонятная игра с передачей фокуса клавиатурного ввода сначала главному окну Notepad, затем дочернему окну редактирования, а затем этим окном самому себе. В сообщениях 104 и 117 редактор посылает главному окну сначала команду «Потерять фокус», а затем «Получить фокус». Посылается также несколько команд IME. 121. И на этом заканчивается обработка активизации окна Notepad. 122-123. Система спрашивает у окна, не надо ли сменить вид курсора в связи со щелчком левой кнопкой мыши на кнопке закрытия окна. Окно предоставляет изменение курсора системе. 124-126. Окно Notepad получает асинхронные извещения о том, что была нажата левая кнопка мыши, курсор еще немного передвинулся, а затем левая кнопка была отпущена. Системе не жалко известить, вдруг эти детали играют какую-то роль для окна. Отрицательная координата yPos не должна удивлять, поскольку координаты здесь отсчитываются вниз/вправо от левого верхнего угла клиентской части окна. 127-128. Окну сообщают, что оно потеряло захват мыши (поскольку кнопка отпущена). 129. Окно получает системную команду закрытия (это прямой результат щелчка на кнопке закрытия). Все дальнейшие сообщения посылаются в порядке выполнения этой команды. 130. Система говорит окну: «Закройся!». В принципе, окно может игнорировать это сообщение, но в данном случае окно не сопротивляется. Далее идет выполнение закрытия. 131-132. У окна редактора спрашивают, не изменен ли в нем текст (т.е. требуется ли запрос о сохранении). Ответ: «Нет, не изменен». 133-134. Окно редактора сообщает родителю о своем закрытии. 135-136. Наконец-то как-то проявилось окно строки состояния. Оно получает команду на уничтожение и тихо подчиняется. 137. Сообщение WM_NCDESTROY следует за WM_DESTROY и вызывает освобождение системной памяти, в которой хранилась информация об окне. 138-141. Позиция главного окна Notepad опять меняется, теперь она становится «никакой». Система будет это учитывать при отображении остальных окон. 142-143. Окну сообщают, что неклиентская область будет перерисована в неактивном состоянии. Окно соглашается. 144-145. Окно перестает быть активным. 146-149. Приложение также перестает быть активным. При этом у редактора зачем-то опять запрашивают позицию выделенного текста. 150-153. Редактор теряет фокус ввода и сообщает об этом родителю. 154-157. Серия сообщений IME. 158-164. Серия сообщений, вызывающих уничтожение главного окна и окна редактора. 165. Завершается обработка команды закрытия окна Notepad (сообщение 130). 166. Завершается обработка системной команды закрытия (сообщение 129).
Варианты заданий В каждом варианте задания следует получить и прокомментировать протокол сообщений, посылаемых в ситуации, которая описана в задании. Сообщения, не имеющие прямого отношения к исследуемой ситуации, можно исключить из протокола. 1. Минимизированное окно программы «Блокнот» активизируется по Alt+Tab, а затем теряет активность таким же образом. 2. В окне редактора «Блокнот» выполняется копирование/вставка фрагмента текста через буфер обмена. 3. В программе «Калькулятор» выполняется операция «2*3=». Клавиши калькулятора нажимаются с помощью мыши. 4. В программе «Калькулятор» выполняется операция «25/2=». Операция задается с клавиатуры компьютера. 5. Некоторый файл перетаскивается с помощью мыши из одного окна «Проводник» в другое такое же окно. 6. В программе «Блокнот» открывается для редактирования существующий файл. 7. В программе «Проводник» удаляется какой-либо файл. 8. Окно программы «Блокнот» с набранным заранее текстом минимизируется, а затем восстанавливает нормальные размеры. Минимизация выполняется с помощью команды системного меню. Контрольные вопросы 1. Что такое процесс и нить? В чем их отличие? 2. Что такое «система, управляемая событиями»? 3. Какую информацию содержит сообщение в Windows? 4. Каковы основные источники сообщений? 5. Какие идентификаторы может пользователь присваивать своим сообщениям? 6. На какие группы можно разделить сообщения от клавиатуры? 7. Какие сообщения посылает мышь? 8. Какие сообщения получает окно при создании? 9. Что означает префикс NC в именах сообщений? 10. Что такое дочерние окна? 11. В каких случаях посылается сообщение WM_NOTIFY? 12. Какие сообщения сопровождают смену активного окна? 13. Что такое сообщение WM_COMMAND? 14. Чем отличаются сообщения WM_COMMAND при различных способах подачи команды? 15. В каких случаях подается сообщение WM_SYSCOMMAND? 16. Какие сообщения получает окно при закрытии? 17. В каких случаях подается сообщение WM_PAINT? 18. В каких случаях подается сообщение WM_TIMER? 19. Каково назначение цикла приема сообщений? 20. В чем назначение функции TranslateMessage? 21. В чем назначение функции DispatchMessage? 22. Как отличаются сообщения, посланные нити, от сообщений, посланных окнам нити? 23. Чем различаются функции GetMessage и PeekMessage? 24. Как приложение может узнать время и координаты, связанные с сообщением? 25. Что делает функция WaitMessage? 26. Что такое оконная функция? 27. Чем отличается оконная функция диалогового окна? 28. Чем различаются синхронный и асинхронный способы посылки сообщений? 29. В каком порядке выбираются для обработки разные типы сообщений? 30. Что такое виртуальная очередь ввода? 31. Какие функции используются для асинхронной посылки сообщений? 32. Какая функция используется для синхронной посылки сообщений? 33. Чем различается обработка синхронных сообщений от нити, владеющей окном, и от других нитей? 34. До каких пор нить, пославшая синхронное сообщение, остается заблокированной? 35. Какую роль играет функция ReplyMessage? 36. Как оконная функция может отличить синхронное сообщение от асинхронного? 37. Как устраняется опасность блокировки нити-отправителя при некорректной работе нити-получателя синхронного сообщения? 38. Какие основные возможности предоставляет программа Spy++? 39. Как узнать хэндл окна, видимого на экране? 40. Как найти на экране окно, зная его хэндл? 41. Какие свойства отображаются для окна? 42. Какие свойства отображаются для сообщения? 43. Как выбрать окно для отслеживания сообщений? 44. Как можно сократить поток отображаемых сообщений? 45. Как отследить сообщения для двух окон?
|