Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС лабы / ОС - Лабораторная работа 1.doc
Скачиваний:
63
Добавлен:
01.06.2015
Размер:
1.18 Mб
Скачать
      1. Цикл приема сообщений

Сообщение проходит в ОС путь от источника, создавшего это сообщение, до приемника, обрабатывающего его. Описание этого пути удобнее начать с конца.

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

Работа нити процесса, владеющей окнами, основана на цикле приема сообщений, который начинает работу после инициализации (создания окон, присвоения начальных значений и т.п.) и продолжается до завершения работы нити. При использовании современных систем программирования (Delphi,VisualC++ и т.п.) цикл приема сообщений может оказаться скрытым от пользователя в теле методов системных классов, однако он тем не менее существует.

Примерная структура цикла приема сообщений выглядит так:

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

Первый параметр функции GetMessageсодержит адрес структуры, куда будет приниматься сообщение. Второй параметр содержит хэндл окна, чьи сообщения будут выбираться из очереди. ЗначениеNULLозначает все окна данной нити. Третий и четвертый параметры – нижняя и верхняя границы идентификаторов принимаемых сообщений. Пара значений0,0означает все сообщения. Функция возвращает0в единственном случае: если принято сообщениеWM_QUIT, которое означает завершение нити. Если в очереди нет требуемых сообщений, функция ожидает их появления. В это время могут работать другие процессы и нити.

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

Функции GetMessageиPeekMessageне дают информации о времени посылки сообщения и о координатах курсора. Если эти данные нужны для правильной обработки сообщения, приложение может вызвать функцииGetMessageTimeиGetMessagePos.

Функция TranslateMessageнеобходима для программ, обрабатывающих клавиатурные сообщения о введенном символеWM_CHARиWM_SYSCHAR.Как было сказано выше, эти сообщения помещаются в очередь на основании анализа сообщений о нажатии/отпускании клавиш.

Функция DispatchMessage(msg)выясняет, какому из окон данной нити адресовано сообщение, вызываетоконную функциюданного окна для обработки сообщения и передает в нее структуру сообщенияmsg. После того, как оконная функция обработает сообщение, цикл приема сообщений продолжает свою работу.

В цикл приема сообщений могут входить дополнительные операторы, выявляющие сообщения, адресованные не окну, а самой нити (сообщения с хэндлом окна, равным NULL), и выполняющие обработку таких сообщений без вызоваDispatchMessage.

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