Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Алгоритм выборки сообщений из очереди потока




Когда поток вызывает GetMessage или PeekMessage, система проверяет флаги состояния очередей потока и определяет, какое сообщение надо обработать

1. Если флаг QS_SENDMESSAGE установлен, система отправляет сообщение соответствующей оконной процедуре GetMessage и PeekMessage контролируют процесс обработки и передают управление потоку сразу после того, как оконная процедура обработает сообщение, вместо этого обе функции ждут следующего сообщения.

2. Если очередь асинхронных сообщений потока не пуста, GetMessage и Peek Message заполняют переданную им структуру MSG и возвращают управление Цикл выборки сообщений (расположенный в потоке) в этот момент обычно обращается к DispatchMessage, чтобы соответствующая оконная процедура обработала сообщение.

3. Если флаг QS_QUIT установлен, GetMessage и PeekMessage возвращают сообщение WM__QUIT (параметр wParam которого содержит указанный код завершения) и сбрасывают этот флаг.

4 Если в очереди виртуального ввода потока есть какие-то сообщения, GetMessage и PeekMessage возвращают сообщение, связанное с аппаратным вводом.

5. Если флаг QS_PAINT установлен, GetMessage и PeekMessage возвращают сообщение WM_PAINT для соответствующего окна

6 Если флаг QS_TIMER установлен, GetMessage и PeekMessage возвращают сообщение WM_TIMER.

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

 

7. Синхронные и асинхронные сообщения, их передача и обработка. Ввод данных с манипулятора «мышь». Обработка сообщений мыши. Ввод данных с клавиатуры. Понятие фокуса ввода. Обработка сообщений от клавиатуры.

 

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

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

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

Рассмотрим, например, какие события произойдут после щелчка кнопкой мыши на кнопке закрытия окна приложения Hellol. Все начнется с того, что Windows отправит асинхронное сообщение WM_SYSCOMMAND оконной процедуре WndProc. Оконная процедура передаст это сообщение на обработку функции DefWindowProc. Функция DefWindowProc реагирует на него, отправляя сообщение WM_CLOSE оконной процедуре. В рассматриваемом примере предусмотрена обработка этого сообщения — вызывается функция DestroyWindow. Однако если не предусмотреть эту обработку, то функция DefWindowProc сделала бы то же самое, то есть вызвала бы функцию DestroyWindow. Функция DestroyWindow заставляет Windows отправить оконной процедуре сообщение WM_DESTROY. И наконец, WndProc, обрабатывая это сообщение, вызывает функцию PostQuitMessage, которая посылает синхронное сообщение WM_QUIT в очередь сообщений приложения. Сообщение WM_QUIT прерывает цикл обработки сообщений в WinMain, и приложение завершает свою работу.

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

Ввод с клавиатуры направляется потоком необработанного ввода (RTT) в очередь виртуального ввода какого-либо потока, но только не в окно. RTT помещает события от клавиатуры в очередь потока безотносительно конкретному окну. Когда поток вызывает GetMessage, событие от клавиатуры извлекается из очереди и перенаправляется окну (созданному потоком), на котором в данный момент сосредоточен фокус ввода.

Чтобы направить клавиатурный ввод в другое окно, нужно указать, в очередь какого потока RIT должен помещать события от клавиатуры, а также "сообщить" переменным состояния ввода потока, какое окно будет находиться в фокусе. Одним вызовом SetFocus эти задачи не решить. Если в данный момент ввод от RIT получает поток 1, то вызов SetFocus с передачей описателей окон А, В или С приведет к смене фокуса. Окно, теряющее фокус, убирает используемый для обозначения фокуса прямоугольник или гасит курсор ввода, а окно, получающее фокус, рисует такой прямоугольник или показывает курсор ввода.

Когда фокус переводится с одного окна на другое обычным способом (например, щелчком окна), теряющее фокус окно получает сообщение WM_KILLFOCUS. Если окно, получающее фокус, принадлежит другому потоку, переменные локального со стояния ввода потока, который владеет окном, теряющим фокус, обновляются так, чтобы показать: окон в фокусе нет. И вызов GetFocus возвращает при этом NULL, заставляя поток считать, что окон в фокусе нет.

Функция SetActiveWindow активизирует в системе окно верхнего уровня и переводит на него фокус:

HWND SetActiveWindow(HWND hwnd);

Оконная процедура окна, которое имеет фокус клавиатуры, принимает сообщения о нажатии клавиши, когда пользователь печатает на клавиатуре. Сообщения о нажатии клавиши - WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN и WM_SYSKEYUP. Типичная оконная процедура игнорирует все сообщения о нажатии клавиши кроме WM_KEYDOWN. Windows посылает сообщение WM_KEYDOWN, когда пользователь нажимает клавишу.

Когда оконная процедура принимает сообщение WM_KEYDOWN, она должна проверить код виртуальной клавиши, который сопровождает сообщение, чтобы установить, как обработать нажатие клавиши. Код виртуальной клавиши находится в параметре wParam сообщения. Как правило, приложение обрабатывает только нажатия клавиши, сгенерированные не символьными клавишами, включая функциональные клавиши, клавиши управления курсором, и клавиши специального назначения типа INS, DEL, HOME и END.


Поделиться:

Дата добавления: 2015-01-29; просмотров: 111; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.008 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты