Запуск цикла обработки сообщений
После вызова функции WinCreateStdWindow окно появится на экране, но оно еще не будет работать. Теперь вы должны запустить цикл обработки сообщений. Основная задача этого цикла - выборка сообщений из очереди приложения и передача их на обработку функции окна, зарегистрированной на предыдущем этапе.
Цикл обработки сообщений выглядит следующим образом:
QMSG qmsg; while(WinGetMsg (hab, &qmsg, 0, 0, 0)) WinDispatchMsg (hab, &qmsg);
Здесь функция WinGetMsg выбирает сообщения из очереди приложения, записывая их в структуру qmsg типа QMSG . Если очередь сообщений пуста, функция переходит в состояние ожидания. Три последних нулевых параметра означают, что из очереди будут выбираться все сообщения для всех окон, созданных в данной задаче.
После того как сообщение выбрано и записано в структуру qmsg, его нужно передать функции окна. Однако вы не можете просто вызвать функцию окна и в качестве одного из параметров передать указатель на данную структуру. Вспомните, мы говорили, что приложение создает функцию окна, но никогда ее не вызывает.
Вместо этого выбранное сообщение передается функции WinDispatchMsg , которая возвращает сообщение системе Presentation Manager и та уже вызывает функцию окна, определенную в вашем приложении.
На первый взгляд такая процедура может показаться бессмысленной, так как система Presentation Manager могла бы и сама выполнять такую обработку внутри себя. Однако цикл обработки сообщений, организованный в приложении, позволяет выполнять дополнительную обработку сообщений перед тем, как они возвратятся системе Presentation Manager и попадут в функцию окна. Такой контроль открывает перед приложением большие возможности в определении поведения своего главного окна. Например, приложение может контролировать весь поток сообщений, проходящих через очередь сообщений этого приложения.
Займемся функцией WinGetMsg , прототип которой приведен ниже:
BOOL WinGetMsg ( HAB hab, // идентификатор Anchor-block PQMSG pqmsgmsg, // указатель на структуру, // куда будет записано сообщение HWND hwndFilter,// фильтр окон ULONG ulFirst, // начальный код сообщения ULONG ulLast); // конечный код сообщения
Через параметр hab функции WinGetMsg передается идентфикатор Anchor-block, полученный от функции WinInitialize . Здесь для вас нет ничего нового.
Через параметр pqmsgmsg вы должны передать функции указатель на структуру типа QMSG , в которую будет записано извлеченное из очереди сообщение.
Если значение параметра hwndFilter не равно нулю, функция WinGetMsg будет выбирать сообщения, предназначенные для всех окон, созданных в рамках данной задачи. Как правило, именно так и поступают. Однако вы можете указать здесь идентификатор какого-либо дочернего окна и организовать обработку сообщений только для него.
Как мы уже говорили, для идентификации каждому сообщению присваивается определенный код. Если значения параметров ulFirst и ulLast равны нулю, функция WinGetMsg будет обрабатывать сообщения с любым кодом. Если же значение параметра ulFirst больше чем ulLast, будут обрабатываться все сообщения, кроме тех, коды которых попали в интервал от ulLast до ulFirst. Аналогично, если значение параметра ulFirst меньше, чем ulLast, будут обрабатываться только такие сообщения, коды которых попадают в интервал от ulFirst до ulLast.
Как правило, обычно значения параметров ulFirst и ulLast устанавливаются равными нулю.