Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпора 130стр.doc
Скачиваний:
93
Добавлен:
15.06.2014
Размер:
2.49 Mб
Скачать

16)Организация асинхронного ввода. Сообщения от манипулятора типа «мышь». Сообщения от клавиатуры (см также 33!!!)

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

Так, нажатие кнопки мыши могло бы заставить окно, которое обрабатывает сообщение WMLBUTTONDOWN, послать 3 асинхронных сообщения разным окнам. Поскольку эти 3 программных события возникают в результате аппаратного события, система обрабатывает их до того, как принимает новое аппаратное событие, инициируемое пользователем.

TranslateMessage. проверяет, не было ли выбрано из очереди ввода сообщение WM_KEYDOWN или WM_SYSKEYDOWN. Если да, функция проверяет, можно ли информацию о виртуальной клавише преобразовать в символьный эквивалент. Если это возможно, TranslateMessage вызывает PostMessage. чтобы поместить в очередь асинхронных сообщений WM_CHAR или WM_SYSCHAR. При следующем вызове GetMessage система проверяет содержимое очереди асинхронных сообщений и, если в ней есть сообщение, выбирает его и возвращает поток. Возвращается либо WM_CHAR, либо VM_SYSCHAR, Но вот GetMessage вызывается еще раз. и система обнаруживает, что очередь асинхронных сообщений пуста. Тогда она проверяет очередь ввода, где и находит сообщение WM_(SYS)KEYUP; именно оно и возвращается.

Поскольку система устроена так, а не иначе, приведенная ниже последовательность аппаратных событий: WM_KEYDOWN WM_KEYUP генерирует такую последовательность сообщений для оконной процедуры (при этом предполагается, что информацию о виртуальной клавише можно преобразовать в ее символьный эквивалент): WM_KEYDOWN WM_CHAR WM_KEYUP

Сообщения. Типы сообщений:

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

Отправление: с помощью функции PostMessage – ставится в очередь и немедленно возвращает управление.

Получение: результат пользовательского ввода путем нажатия клавиш (например, WM_KEYDOWN и WM_KEYUP), это символы, введенные с клавиатуры (WM_CHAR), результат движения мыши (WM_MOUSEMOVE) и щелчков кнопки мыши (WM_LBOTTONDOWN). Кроме этого синхронные сообщения включают в себя сообщение от таймера (WM_TIMER), сообщение о необходимости плановой перерисовки (WM_PAINT) и сообщение о выходе из программы (WM_QUIT)

  • асинхронные сообщения (nonqueued) – сообщения, передающиеся непосредственно окну, когда Windows вызывает оконную процедуру.

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

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

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

Цикл обработки сообщений и оконная процедура работают не параллельно. Когда оконная процедура обрабатывает сообщение, то это результат вызова функции DispatchMessage в WinMain. DispatchMessage не завершается до тех пор, пока оконная процедура не обработала сообщение.

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

Когда программа для Windows начинает выполняться, Windows строит для программы очередь сообщений (message queue). В этой очереди хранятся сообщения для любых типов окон, которые могли бы быть созданы программой. Небольшая часть программы, которая называется циклом обработки сообщений (message loop), выбирает эти сообщения из очереди и переправляет их соответствующей оконной процедуре. Другие сообщения отправляются непосредственно оконной процедуре, минуя очередь сообщений.

GetMessageэто функция, при помощи которой цикл обработки начинает извлекать сообщения из очереди.

Обработка клавиатурных сообщений.

Синхронизация событий клавиатуры.

Основанная на сообщениях архитектура Windows идеальна для работы с клавиатурой:

  1. приложение узнает о нажатиях клавиш посредством сообщений, которые посылаются оконной процедуре: нажимание и отпускание клавиш.

  2. драйвер клавиатуры передает информацию о нажатии клавиш в Windows.

  3. Windows сохраняет эту информацию (в виде сообщений) в системной очереди сообщений.

  4. передача сообщения клавиатуры, по одному за раз, в очередь сообщений программы, содержащей окно, имеющее фокус ввода (input focus).

  5. отправление программой сообщения соответствующей оконной процедуре (с помощью функции DispatchMessage).

Игнорирование событий клавиатуры.

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

Понятие фокуса ввода

Когда на клавиатуре нажата клавиша, только одна оконная процедура может получить сообщение об этом.

Окно, имеющее фокус ввода – это окно, которое получает это сообщение клавиатуры.(активное окно либо дочернее активного)

Если активное окно минимизировано, то окна с фокусом ввода нет.

WM_SETFOCUS/ WM_KILLFOCUS - окно получило/потеряло фокус ввода

GetFocus/ SetFocus - позволяет узнать/изменить окно, владеющее фокусом ввода;

Категории клавиатурных сообщений:

  • аппаратные (keystrokes) – нажатие или опускание клавиш, генерирующих значок или клавиши переключения, функциональные, управления курсором и т.д.

  • символьные (characters) – нажатие клавиш с использованием таких клавиш как <Ctrl>, <Shift> и <CapsLock> - сочетание даёт символ, например строчные и прописные буквы.

Аппаратные сообщения.

Виды аппаратных сообщений:

  • несистемные– это сообщения WM_KEYDOWN и WM_KEYUP

WM_KEYDOWN и WM_KEYUP вырабатываются для клавиш, которые нажимаются и отпускаются без участия клавиши <Alt>. Приложение использует или не использует эти сообщения клавиатуры. Windows их проигнорирует.

  • системные - это сообщения WM_SYSKEYDOWN и WM_SYSKEYUP

WM_SYSKEYDOWN и WM_SYSKEYUP важны для Windows, а не для приложений. Эти сообщения обычно вырабатываются при нажатии клавиш в сочетании с клавишей <Alt>.

Программы обычно игнорируют сообщения WM_SYSKEYDOWN и WM_SYSKEYUP и передают их в функцию DefWindowProc. Если не передать системные аппаратные сообщения в DefWindowProc. происходит запрет всех операций с клавишей <Alt> (команды меню, <Alt+Tab> и др.), когда окно программы имеет фокус ввода. Аппаратные сообщения клавиатуры становятся в очередь. Приложение с помощью функции GetMessageTime получить время нажатия и отпускания клавиши относительно старта системы.

Виртуальный код клавиши (virtual key code) - идентифицирует нажатую или отпущенную клавишу. (wParam)

Коды виртуальных клавиш имеют символьные обозначения, определенные в заголовочных файлах Windows, и имеют префикс VK_.

Определение состояния клавиш сдвига и клавиш-переключателей.

GetKeyState- функция, получающая состояние любой виртуальной клавиши:

Информация о текущем положении клавиши используется функция GetAsyncKeyState.

Символьные сообщения.

Виды символьных сообщений:

  • несистемные – WM_CHAR, WM_DEADCHAR;

  • системные – WM_SYSCHAR, WM_SYSDEADCHAR;

В большинстве случаев программы для Windows могут игнорировать все сообщения за исключением WM_CHAR.( обрабатывать символы клавиатуры) Параметр wParam – это код символа ASCII;

Обработка сообщений от мыши.

GetSystemMetrics, передавая в качестве параметра значение SM_MOUSEPRESENT – определение присутствие мыши: если мышь есть – возврат ненулевого значения. SM_CMOUSEBUTTONS - определение количества кнопок.

При перемещение мыши, Windows перемещает по экрану растровую картинку - курсор мыши,

точно указывающий положение мыши на экране.

Сообщения мыши могут быть связаны:

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

Сообщения, получаемые оконной процедурой: WM_MOUSEMOVE – о перемещении мыши по рабочей области окна;WM _LBUTTONDOWN, WM_RBUTTONDOWN,

WM_MBUTTONDOWN – о нажатии кнопки мыши внутри рабочей области окна;WM_LBUTTONUP, WM_RBUTTONUP, WM_MBUTTONUP – об отпускании кнопки мыши внутри рабочей области окна; WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, WM_MBUTTONDBLCLK – о двойном щелчке кнопки мыши внутри рабочей области окна;

lParam – содержит положение мыши: младшее слово – это координата Х, а старшее – координата Y относительно верхнего левого угла рабочей области окна, wParam – показывает состояние кнопок мыши и клавиш <Shift> и <Ctrl>, проверяемый с помощью битовых масок, определенных в заголовочных файлах:

При щёлкании кнопкой мыши в рабочей области неактивного окна, Windows сделает активным окно, в котором был произведен щелчок, и затем передаст оконной процедуре сообщение WM_LBUTTONDOWN.

Обработка нажатия клавиш <Shift> и <Ctrl> и кнопок мыши

При получении сообщений мыши, связанных с рабочей областью окна, через параметр wParam передается значение, позволяющее определить, были ли одновременно с этим нажаты кнопки мыши или клавиши <Shift> и <Ctrl> клавиатуры.

GetKeyState возвращает состояние:

  1. кнопок мыши или клавиш <Shift> и <Ctrl>, используя виртуальные коды клавиш VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_SHIFT и VK_CONTROL.

  2. кнопки мыши и клавиши в связи с обрабатываемым в данный момент сообщением, т.е. информация о состоянии должным образом синхронизируется с сообщением.

Двойные щелчки мыши – это два, следующих одно за другим в быстром темпе, щелчка мыши.

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

wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;

  • с нерабочей областью окна – это сообщения мыши, которые Windows посылает оконной процедуре, связанные с нерабочей областью (нерабочая область включает в себя панель заголовка, меню, рамку окна и полосы прокрутки).

Нет необходимости обрабатывать сообщения мыши нерабочей области – их передают в DefWibdowProc, чтобы Windows могла выполнить системные функции.

Сообщения мыши нерабочей области почти полностью такие же, как и сообщения мыши рабочей области. В названия сообщений входят буквы NC, что означает нерабочая (nonclient) – WM_NCMOUSEMOVE – перемещение мыши внутри нерабочей области окна.

wParam – показывает зону нерабочей области, в которой произошло перемещение или щелчок. lParam – содержит в младшем слове значение координаты X, а в старшем – Y, являющиеся координатами экрана, а не координатами рабочей области. Значения координат X и Y верхнего левого угла экрана равны 0.

Приложение может преобразовать экранные координаты в координаты рабочей области окна и наоборот с помощью функций Windows ScreenToClient и ClientToScreen – функции преобразования

Сообщение WM_NCHITTEST (тест попадания в нерабочую область) – это сообщение, предшествующее всем остальным сообщениям мыши рабочей и нерабочей области.

В приложениях Windows это сообщение обычно передается в DefWindowProc. В этом случае Windows использует сообщение WM_NCHITTEST для выработки всех остальных сообщений на основе положения мыши.

Если функция DefWindowProc после обработки сообщения WM_NCHITTEST возвращает значение HTCLIENT, то Windows преобразует экранные координаты в координаты рабочей области и вырабатывает сообщение мыши рабочей области.

Используя WM_NCHITTEST, приложение может полностью запретить работу с мышью в том или ином окне.

Захват мыши –приложение может получать сообщения от мыши, когда курсор мыши находится вне окна.

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

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

ReleaseCapture – функция освобождения мыши, т.е. возврат обработки мыши в нормальный режим.