При таком объяснении процесса генерации и отработки сообщений можно говорить, что сообщение поступает в приложение, но в действительности одновременно с созданием каждого потока создается и очередь к нему. В очередь потока поступают сообщения непосредственно потоку и всем окнам, созданным при выполнении этого потока. Для краткости обычно говорят, что сообщение «поступает в окно».

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

Итак, сообщение приходит, выполняется закрепленная за ним оконная функция, которая обрабатывает сообщение, а после ее завершения приложению опять нечего делать. Но сообщения приходят асинхронно, а где асинхронность, там и очередь. Легко может возникнуть ситуация, когда одновременно поступило сообщение Назначение и структура сообщений от таймера и пользователь щелкнул мышью. Приложение может начать обработку сообщения таймера, но надо запомнить координаты щелчка мышью. Кроме того, в момент поступления сообщения процессор может быть выделен другому потоку. Выход из этой ситуации довольно прост. Необходимо унифицировать структуру данных о заявке на выполнение каких-либо вычислений, создать для организации очереди массив (кольцевой буфер) и разделить во времени процессы поступления и обработки сообщений.

Все сообщения поступают в очередь. По мере освобождения процессора от отработки ранее поступивших сообщений очередь просматривается, из нее выбирается и обслуживается следующее сообщение. Такой подход типичен для организации вычислительного процесса в многозадачных операционных системах. Но традиционно очередь создавалась внутри ОС и состояла из задач. Новшество Windows состоит в том, что этот прием применен и для планирования работы каждого приложения. При этом концепциями очереди и заявки на обслуживание вынужден оперировать и прикладной программист. В частности, приложение должно извлекать сообщение из очереди функцией GetMessageC) или PeekMessage().


⇐ Предыдущая| |Следующая ⇒