О чём не пишут в книгах по Delphi - [14]

Шрифт
Интервал

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

Функция >TranslateMessage, которая обычно вызывается в петле сообщений, служит для трансляции клавиатурных сообщении (если петля сообщений реализуется только для обработки сообщении невидимым окнам, которые использует, например, COM/DCOM, или по каким-то другим причинам ввод с клавиатуры не обрабатывается или обрабатывается нестандартным образом, вызов >TranslateMessage можно опустить). Когда пользователь нажимает какую-либо клавишу на клавиатуре, система посылает окну, находящему в фокусе, сообщение >WM_KEYDOWN. Через параметры этого сообщения передаётся виртуальный код нажатой клавиши — двухбайтное число, которое определяется только положением нажатой клавиши на клавиатуре и не зависит от текущей раскладки, состояния клавиш и т.п. Функция >TranslateMessage. обнаружив такое сообщение, добавляет в очередь (причем не в конец, а в начало) сообщение >WM_CHAR, в параметрах которого передается код символа, соответствующего нажатой клавише, с учетом раскладки, состояния клавиш , и т. п. Именно функция >TranslateMessage по виртуальному коду клавиши определяет код символа. При этом нажатие любой клавиши приводит к генерации >WM_KEYDOWN, а вот >WM_CHAR генерируется не для всех клавиш, а только для тех, которые соответствуют какому-то символу (например, не генерирует >WM_CHAR нажатие таких клавиш, как , , функциональных клавиш).

Примечание

У многих компонентов VCL есть события >OnKeyDown и >OnKeyPress. Первое возникает при получении компонентом сообщения >WM_KEYDOWN, второе — сообщения >WM_CHAR.

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

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

В некоторых случаях избежать временного зависания программы помогает организация локальной петли сообщений. Если обработчик сообщения, для работы которого требуется много времени, содержит цикл, в него можно вставить вызовы функции >PeekMessage, которая позволяет проверить, есть ли в очереди сообщения. Если сообщения обнаружены, нужно вызвать >DispatchMessage для передачи их требуемому окну. В этом случае сообщения будут извлекаться из очереди и обрабатываться до завершения работы обработчика. Блок-схема программы, содержащей локальную петлю сообщений, показана на рис. 1.5 (для краткости в главной петле сообщений показаны только две самых важных функции: >GetMessage и >DispatchMessage, хотя и в этом случае главная петля целиком выглядит так же, как на рис. 1.4).

При использовании локальной петли сообщений существует опасность бесконечной рекурсии. Рассмотрим это на простом примере: предположим, что сложный код, содержащий локальную петлю сообщений, выполняется при нажатии некоторой кнопки на форме приложения. Пока обработчик выполняется, нетерпеливый пользователь может снова нажать кнопку, запустив вторую активацию обработчика нажатия кнопки, и так несколько раз. Конечно, организовать таким образом очень глубокую рекурсию пользователь вряд ли сможет (терпения не хватит), но часто даже то, что несколько активаций обработчика вызваны рекурсивно, может привести к неприятным последствиям. А если программа организует локальную петлю сообщений в обработчике сообщений таймера, то здесь рекурсия действительно может углубляться до переполнения стека. Поэтому при организации петли сообщений следует принимать меры против рекурсии. Например, в случае с кнопкой в обработчике ее нажатие можно запретить (>Enabled := False), и вновь разрешить только после окончания обработки, тогда пользователь не сможет нажать кнопку во время работы локальной петли сообщений. В очередь можно поставить сообщение, не привязанное ни к какому окну. Это делается с помощью функции >PostThreadMessage. Такие сообщения необходимо самостоятельно обрабатывать в петле сообщений, потому что функция >DispatchMessage их просто игнорирует.

Рис. 1.6. Блок-схема программы с локальной петлей сообщений


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


Рекомендуем почитать
Язык PL/SQL

В учебно-методическом пособии рассматриваются основы языка программирования PL/SQL, реализованного в системе управления базами данных Oracle Database Server. Приводятся сведения о поддерживаемых типах данных, структуре программ PL/SQL и выполнении SQL-предложений в них. Отдельно рассмотрено создание хранимых в базах данных Oracle программ PL/SQL – процедур, функций, пакетов и триггеров.


Пишем драйвер Windows на ассемблере

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


Язык программирования С# 2005 и платформа .NET 2.0.

В этой книге содержится описание базовых принципов функционирования платформы .NET, системы типов .NET и различных инструментальных средств разработки, используемых при создании приложений .NET. Представлены базовые возможности языка программирования C# 2005, включая новые синтаксические конструкции, появившиеся с выходом .NET 2.0, а также синтаксис и семантика языка CIL. В книге рассматривается формат сборок .NET, библиотеки базовых классов .NET. файловый ввод-вывод, возможности удаленного доступа, конструкция приложений Windows Forms, доступ к базам данных с помощью ADO.NET, создание Web-приложений ASP.NET и Web-служб XML.


Вариации на тему STL. Адаптер обобщенного указателя на функцию-член класса

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


Информационная технология. Руководство по управлению документированием программного обеспечения

ГОСУДАРСТВЕННЫЙ СТАНДАРТ РОССИЙСКОЙ ФЕДЕРАЦИИИнформационная технологияРУКОВОДСТВО ПО УПРАВЛЕНИЮ ДОКУМЕНТИРОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯInformation technology. Guidelines for the management of software documentationИздание официальноеДата введения 1994-07-01ГОССТАНДАРТ РОССИИ Москва© Издательство стандартов, 1994.


Самоучитель UML

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