Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции-ТРПС.doc
Скачиваний:
13
Добавлен:
15.11.2018
Размер:
810.5 Кб
Скачать

5.2.11. Потоки и сообщения

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

В Win32 можно установить отдельный поток, выполняющий, например, длительные операции, в то время как главный поток приложения, владеющий окном, будет обрабатывать все сообщения, принимаемые приложением.

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

5.2.12. Оконная функция – функция обратного вызова

Чтобы понять, что такое функция обратного вызова, вспомним, что в любой операционной системе вызов большинства функций предназначен для запроса некоторого сервиса у операционной системы. Например, для открытия файла используется вызов функции fopen(). Другими словами, вашей программе нужен какой-либо сервис, и он запрашивается у операционной системы вызовом соответствующей функции, код которой располагается в одной из системных библиотек. Это – обычные функции, и большинство Win32 API функций принадлежит к данному классу.

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

Оконная функция (именуется также оконной процедурой) связанна с классом окна, который приложение регистрирует при своем запуске. С этого момента ядро Windows “знает” адрес оконной функции и может ее вызывать, использую данный адрес. При этом все вызовы функции окна имеют форму сообщений.

5.2.13. Синхронные и асинхронные сообщения

Одни и те же Windows сообщения могут быть как синхронными (queued), так и асинхронными (nonqueued). Асинхронными сообщениями называются сообщения, помещаемые Windows в очередь сообщений приложения, и которые затем извлекаются и диспетчеризируются в цикле обработки сообщений. Синхронные сообщения передаются непосредственно окну, когда Windows вызывает оконную процедуру. В результате оконная процедура получает все предназначенные для окна сообщения, как синхронные, так и асинхронные.

Асинхронные сообщения помещаются в очередь сообщений в одно время, а обрабатываться могут в другое. Синхронные – посылаются напрямую в оконную процедуру и тут же обрабатываются.

Асинхронными становятся сообщения, в основном, тогда, когда они являются результатом пользовательского ввода, путем нажатия клавиатурных клавиш, например, WM_KEYDOWN и WM_KEYUP; как результат движения мыши или щелчков кнопок мыши. Также к асинхронным сообщениям относятся сообщения таймера WM_TIMER или сообщение завершения цикла обработки сообщений WM_QUIT. Порой асинхронные сообщения являются результатом синхронных сообщений, и наоборот.

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

Некоторые сообщения являются результатом вызова определенных функций Win32 API. Например, когда ваше приложение создает окно, вызывает функцию CreateWindowEx(), Windows отправляет оконной процедуре синхронное сообщение WM_CREATE. Когда же вы вызываете функцию UpdateWindow(), Windows помещает в очередь приложения асинхронное сообщение WM_PAINT.

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

Часто возникает необходимость того, чтобы оконная функция сохраняла информацию, полученную в одном сообщении, и использовала ее при обработке другого сообщения. Такую информацию следует описывать в оконной процедуре в виде статических переменных.