<<
>>

Обработка сообщений в оконной функции

Оконная функция призвана организовать адекватную реакцию со стороны Win- dows-приложения на действия пользователя и поддерживать в актуальном состо- янии то окно приложения, сообщения которого она обрабатывает.
Приложение может иметь несколько оконных функций. Их количество определяется количе- ством классов окон, зарегистрированных в системе функцией Register Сlаss(Ех). Если вы помните, функции RеgistеrСlаss(Ех) посредством экземпляра структуры WNDСLАSS передается указатель на определенную оконную функцию Windows-приложения. Данная функция до конца работы приложения связана с экземплярами окон, ко- торые, в свою очередь, создаются другой функцией API — СrеаtеWiпdоwЕХ. Когда для окна Windows-приложения появляется сообщение, операционная система Windows производит вызов соответствующей оконной функции. Ранее мы для упрощения говорили, что единственный источник появления сообщений — очередь сообщений приложения, но это не совсем так. Дело в том, что сообщения, в зависимости от источника их появления в оконной функции, могут быть двух типов: синхронные и асинхронные. К синхронным сообщениям относятся те сооб- щения, которые помещаются в очередь сообщений приложения и терпеливо ждут момента, когда они будут выбраны функцией GеtМеssаgе. После этого поступив- шие сообщения попадают в оконную функцию, где и производится их обработка. Асинхронные сообщения подобно пожарной машине попадают в оконную функ- цию в экстренном порядке, минуя все очереди. Асинхронные сообщения, в частно- сти, инициируются некоторыми функциями Win32 API, такими как СrеаtеWiп- dow(Ex) или UpdateWIndow. Координацию синхронных и асинхронных сообщений осуществляет Windows. Если рассматривать синхронное сообщение, то его извлече- ние производится функцией GetMessage с последующей передачей обратно в Windows функцией Dispatch Message. Асинхронное сообщение, независимо от ис- точника, который инициирует его появление, сначала попадает в Windows и за- тем — в нужную оконную функцию.
Для чего реализуется именно такая схема, неужели функции Dispatch Message нельзя сразу передать сообщение в оконную функцию? Если бы это было так, в системе появилось бы единственное приложение-монополист, которое захвати- ло бы все процессорное время своим циклом обработки сообщений. В схеме, реа- лизованной в Windows, обработка сообщений приложением проводится в два эта- па: на первом этапе приложение выбирает сообщение из очереди и отправляет его обратно во внутренние структуры Windows; на втором этапе Windows вызывает нужную оконную функцию приложения, передавая ей параметры сообщения. Пре- имущество этой схемы в том, что Windows самостоятельно решает все вопросы организации эффективной работы приложений. Таким образом, при поступлении сообщения Windows вызывает оконную функ- цию и передает ей ряд параметров. Все они берутся из соответствующих полей сообщения. В нотации языка C/C++ заголовок оконной функции описан следую- щим образом (см. листинг 16.1): LRЕSULТ CALLBACK WindowProc (НWND hWпd, UINТ message, WРАRАМ wРаrаm, LРАRАН 1Рагаm) Здесь hWnd — дескриптор окна, которому предназначено сообщение; message — идентификатор сообщения, характеризующий тип сообщения; wParam и IParam — дополнительные параметры, являющиеся копиями соответствующих полей струк- туры поступившего сообщения. Оставшиеся два поля структуры MSG: time и POINT — используются довольно редко, и при необходимости их значения можно извлечь непосредственно из эк- земпляра структуры сообщения. В нашем примере Windows-приложения строки 164-167 обозначают начало оконной функции. Параметры этой функции Windows помещает в стек. Чтобы можно было работать с ними, используя символические имена, после заголовка функции поместим директиву ARG (см. главу 15). Windows требует, чтобы оконная функция сохраняла значения регистров EBI, EDI и ESI. Причина — оконная функция должна быть рекурсивной. Например, воз- можна ситуация, когда несколько классов окон применяют одну и ту же оконную функцию для обработки сообщений, поступающих в созданные на базе этих клас- сов окна.
Имеет смысл сохранять не только названные регистры, используемые самой системой Windows, но и другие (за исключением ЕАХ), если они задей- ствованы в оконной функции. Исходя из требования рекурсивности, все пе- ременные, используемые в оконной функции, должны быть локальными. Чтобы удовлетворить требование сохранения регистров, лучше применить (строка 166 листинга 16.4) соответствующее средство транслятора ассемблера — директиву USES (см. также главы 10 и 15). При этом транслятор вставляет в начало и конец окон- ной функции соответствующую последовательность команд ассемблера PUSH. Вы можете убедиться в этом, посмотрев файл листинга (файл .1st) программы из лис- тинга 16.4 после ее трансляции. Центральным местом оконной функции является синтаксическая конструкция, в задачу которой входит распознавание поступившего сообщения по его типу (параметр message) и передача управления на ту ветвь кода оконной функции, ко- торая продолжает далее работу с параметрами сообщения. В языке C/C++ (см. листинг 16.1) для этого используется оператор switch (переключатель). В языке ассемблера такого средства нет, поэтому его приходиться моделировать (см. гла- ву 11). В листинге 16.4 строки 168-174 показывают, как это можно сделать с по- мощью команды СМР, а также команд условного (JЕ) и безусловного (JМР) переходов. Соответствие символических имен константам, обозначающим тип сообщений Windows, приведено во включаемом файле wiпdоwsА.h. Совершенно необязатель- но анализировать типы всех возможных сообщений, параметры которых переда- ются в оконную функцию. Структуру, подобную строкам 168-174, и вообще струк- туру всей оконной функции можно сравнить с ситом, а сообщения — с зернами разной величины. Отверстия в сите непростые — каждое из них пропускает зерно своего размера. Зерна (сообщения) в сите (оконной функции) не задерживаются, попав в него, они через одно из отверстий обязательно уходят. Уходят куда? Это опять-таки определяется особой структурой нашего сита. Представьте, что к каж- дому отверстию припаяна трубка, которая определяет, куда данное зернышко по- падет для дальнейшей обработки.
Таким образом, каждому сообщению, попадаю- щему в оконную функцию, соответствует ветвь в коде процедуры, которая начинает обработку этого сообщения. В ходе этой обработки, возможно, понадобится вызов других функций или применение синтаксических конструкций, подобных описан - ному ситу, для дальнейшей более тонкой селекции сообщений, но уже одного типа (по полям IРаrаm или wParam). Для наглядности аналогию структуры оконной функ- ции с ситом можно упрощенно представить в виде схемы (рис. 16.1). Представленная схема показывает, что оконная функция, обрабатывающая со- общения, имеет одну точку входа и множество точек выхода. Выход осуществля- ется из той ветви оконной функции, где обрабатывалось сообщение. Сообщения,
Рис. 16.1. Абстрактное представление структуры оконной функции Windows

для которых не предусмотрена отдельная обработка, должны обрабатываться функ- цией DеfWiпdоwРrос (строки 219—227). Эта процедура по отношению к переданным ей сообщениям предпринимает действия по умолчанию. В принципе, ей можно передавать на обработку все сообщения, что в контексте рассмотренной ранее аб- стракции означает сито, содержащее одно отверстие, в которое проваливаются все поступающие сообщения. По завершении работы оконная функция формирует значение в регистре ЕАХ. Если сообщение обрабатывалось в оконной функции, то в ЕАХ необходимо помес- тить нулевое значение. Если обработка осуществлялась по умолчанию, то есть функцией DefWindowProc, то в ЕАХ уже сформировано возвращаемое значение, и именно его нужно возвратить в качестве результата работы оконной функции. В нашем примере оконная функция обрабатывает три сообщения: создание окна WМ_СRЕАТЕ, перерисовку области окна WМ_РАINТ, закрытие окна WМ_DЕSТRОY. Более подробно с условиями возникновения и обработкой этих и других сооб- щений можно познакомиться в литературе по Windows, где эти вопросы освеще- ны более полно.

<< | >>
Источник: В. И. Юров. Assembler. Учебник для вузов. 2-е изд. 2003

Еще по теме Обработка сообщений в оконной функции:

  1. Функции журналистики. Понятие функцию Многообразие социальных и информационных потребностей общества – объективная основа функций журналистики.
  2. “Не язык — функция поэта, а поэт — функция языка”
  3. ИНФОРМАЦИЯ: ОБРАБОТКА ПОСЛЕДОВАТЕЛЬНАЯ (
  4. ИНФОРМАЦИЯ: ОБРАБОТКА ПАРАЛЛЕЛЬНАЯ
  5. Статистическая обработка.
  6. ТЕОРИЯ УРОВНЕЙ ОБРАБОТКИ
  7. Обработка материалов
  8. Обработка результатов
  9. ГЛАВА ДЕВЯТАЯ ОБРАБОТКА ИНФОРМАЦИИ В УМЕ
  10. Алгоритм обработки результатов.
  11. ДАННОЕ: ОБРАБОТКА СТАТИСТИЧЕСКАЯ
  12. Обработка материала
  13. Пример обработки протокола.