Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
257-288.doc
Скачиваний:
2
Добавлен:
11.11.2019
Размер:
356.35 Кб
Скачать

Виртуальные коды клавиш, которые не генерируют сообщения wm_char

Обозначение константы

Значение (десятичное)

Клавиша

VK_CLEAR

12

Цифра 5 на дополнительной клавиатуре (Num Lock выключена)

VK_SHIFT

16

Shift

VK_CONTROL

17

Ctrl

VK_PAUSE

19

Pause

VK_CAPITAL

20

Caps Lock

VK_PRIOR

33

PgUp

VK_NEXT

34

PgDn

VK_END

35

End

VK_HOME

36

Home

VK_LEFT

37

VK_UP

38

VK_RIGHT

39

VK_DOWN

40

VK_INSERT

45

Ins

VK_DELETE

46

Delete

VK_F1

112

F1

VK_F2

113

F2

VK_F3

114

F3

VK_F4

115

F4

VK_F5

116

F5

VK_F6

117

F6

VK_F7

118

F7

VK_F8

119

F8

VK_F9

120

F9

VK_F10

121

F10

VK_F11

122

F11

VK_F12

123

F12

VK_NUMLOCK

144

Num Lock

VK_SCROLL

145

Scroll Lock

Параметр nChar содержит значение, называемое виртуальным кодом клавиш (табл. 9.1), определяющим нажатую клавишу; nRepCnt определяет количество повторений нажатий клавиши; nFlags определяет скэн-код, предыдущее состояние клавиши, контекстный код в соответствии с табл. Б12 приложения Б.

Функции CWnd::OnKeyDown() и CWnd::OnKeyUp() используют виртуальный код клавиш, чтобы выполнить переход к соответствующей подпрограмме. В табл. 9.1 приведен список виртуальных кодов клавиш, которые не генерируют сообщения WM_CHAR. Клавиши, генерирующие сообщения WM_CHAR, описаны в следующем параграфе. Они обрабатываются функцией обработки сообщения WM_CHAR, которая идентифицирует их по коду символа.

Для проверки одновременного нажатия двух клавиш, например, Ctrl и Home, необходимо при генерации сообщения WM_KEYDOWN, вызванного нажатием одной клавиши, определить состояние другой клавиши. Для определения состояния клавиши при генерации сообщения WM_KEYDOWN функция CWnd::OnKeyDown() должна вызывать функцию ::GetKeyState(). В качестве аргумента в функцию ::GetKeyState()передается виртуальный код клавиши (табл. 9.1), состояние которой надо проверить. Прототип этой функции такой:

SHORT GetKeyState( int nVirtKey );

Возвращаемое значение свидетельствует о том, была ли клавиша нажата, отпущена или переключена. Если клавиша нажата, то старший бит значения, возвращаемого функцией ::GetKeyState(), устанавливается в 1. Если клавиша отпущена, то в старшем бите 0. Проверка значения старшего бита организована в следующем примере:

if (::GetKeyState(VK_SHIFT)& 0x8000)//была нажата клавиша SHIFT

Если клавиша переключалась во время генерации сообщения WM_KEYDOWN, то младший бит значения результата функции ::GetKeyState() устанавливается в 1. Такими клавишами, которые меняют свое состояние, являются Caps Lock, Num Lock и Scroll Lock. Их включенное состояние отмечается на клавиатуре зажиганием специального индикатора (если он имеется). Следующий пример определяет переключение клавиши Caps Lock.

if (::GetKeyState (VK_CAPITAL) & 0x0001) //переключается //клавиша Caps Lock

Обратите внимание: функция ::GetKeyState() указывает, была ли клавиша нажата или переключена при генерации сообщения WM_KEYDOWN. Она не возвращает текущее состояние клавиши, которое могло измениться за время обработки сообщения.

Текущее состояние клавиши можно получить, вызывая Win32 API функцию ::GetAsyncKeyState(), прототип которой определен таким образом:

SHORT GetAsyncKeyState( int vKey);

Функция ::GetAsyncKeyState() устанавливает соответствующий бит в 1, если проверяемая клавиша была нажата. Ей передается в качестве аргумента один из 256 возможных виртуальных кодов клавиш, значения которых приводятся в табл.Б12 приложения Б.

Рассмотрим особенности использования клавиш для прокручивания текста в окне представления. Как известно, для прокручивания текста используются полосы прокрутки. Полоса прокрутки состоит из прямоугольной области со стрелками на концах и ползунком. Можно выполнить щелчок мышью на самой полосе выше или ниже (левее или правее) ползунка или на стрелках в концах полосы. Эти манипуляции мышью приведут к изменению положения ползунка и прокрутке текста. Как мы знаем, источником сообщений могут быть любые действия с мышью и клавиатурой. Класс CScrollView предоставляет обработчики для каждого из сообщений, вызванных щелчком на полосе прокрутки, которые прокручивают текст и изменяют положение ползунка полосы прокрутки. Каждое сообщение полосы прокрутки сопровождается кодом, идентификатор которого имеет префикс SB_ и указывает на то, что произошло специальное действие прокрутки. На рис. 9.1 показано, какие коды передаются при щелчках на полосе прокрутки.

Рис. 9.1. Коды SB_, передаваемые с сообщениями полосы прокрутки

Функция CWnd::OnKeyDown() обрабатывает каждое нажатие клавиши. При этом окну представления передается сообщение посредством вызова функции CWnd::SendMessage(). Напомним прототип функции:

LRESULT SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );

Параметры функции имеют такой смысл: message — идентификатор посылаемого сообщения; wParam и lParam определяют дополнительную зависимую от сообщения информацию.

Если нажата любая из клавиш управления курсором, Home, End, PgDn, PgUp, то функция CWnd::OnKeyDown() обрабатывает их нажатие и посылает окну представления одно из тех сообщений, которые обычно передаются полосой прокрутки. Эти сообщения имеют идентификаторы WM_VSCROLL и WM_HSCROLL и передаются в функцию CWnd::SendMessage() в качестве первого аргумента. Одним из параметров сообщений WM_VSCROLL и WM_HSCROLL является код прокрутки (scroll-bar code), который идентифицирует запрос пользователя на выполнение прокрутки. Этот код имеет значения, начинающиеся с префикса SB_. Значение кода прокрутки передается в качестве второго аргумента в функцию CWnd::SendMessage(). Например, при нажатии клавиши «», функция CWnd::OnKeyDown() обрабатывает сообщение с идентификатором WM_VSCROLL, который отражает его связь с вертикальной полосой прокрутки. Посылается оно с кодом SB_LINEDOWN, отображающим специальное действие полосы прокрутки:

if (nChar == VK_DOWN) // стрелка вниз SendMessage (WM_VSCROLL, SB_LINEDOWN);

Когда обработчик сообщения WM_VSCROLL, предоставляемый классом CScrollView, обрабатывает это сообщение, он прокручивает текст на одну строку вниз.

В табл. 9.2 приведен список клавиш, нажатие на которые обрабатывается функцией CWnd::OnKeyDown(). Термин «страница» относится к прокручиваемому расстоянию, равному 1/10 размера документа в направлении прокрутки, термин «строка» — к расстоянию, равному 1/10 размера страницы. Эти расстояния можно изменять, вызывая функцию CScrollView::SetScrollSizes().

Т а б л и ц а 9.2

Нажатия клавиш прокрутки, обрабатываемые функцией OnKeyDown() программы TextDemo

Клавиша

Прокрутка

Сообщение, передаваемое окну представления

На один символ влево

WM_HSCROLL, SB_LINEUP

На один символ вправо

WM_HSCROLL, SB_LINEDOWN

На одну строку вверх

WM_VSCROLL, SB_LINEUP

На одну строку вниз

WM_VSCROLL, SB_LINEDOWN

На одну позицию вправо

WM_HSCROLL, SB_LINERIGHT

На одну позицию влево

WM_HSCROLL, SB_LINELEFT

Home

На первую позицию строки

WM_HSCROLL, SB_LEFT

Ctrl+Home

На первую позицию первой строки

WM_VSCROLL, SB_TOP

End

На последнюю позицию строки

WM_HSCROLL, SB_RIGHT

Ctrl+End

На последнюю позицию последней строки

WM_VSCROLL, SB_BOTTOM

PgUp

На одну страницу вверх

WM_VSCROLL, SB_PAGEUP

PgDn

На одну страницу вниз

WM_VSCROLL, SB_PAGEDOWN

До передачи окну сообщения, в результате обработки которого прокручивается текст, функция OnKeyDown() класса представления должна проверить, видима ли соответствующая полоса прокрутки. Обработка сообщений, посылаемых окну от скрытой полосы прокрутки недопустима. MFC скрывает горизонтальную полосу прокрутки, если окно представления имеет такую же ширину, как текст (или большую), и скрывает вертикальную полосу прокрутки, если окно представления имеет такую же высоту, как текст (или большую). Для получения размеров текста вызывают функцию CScrollView::GetTotalSize(), а для получения размера окна представления — функцию CWnd::GetClientRect(). Прототипы этих функций рассматривались ранее. Ниже приведен фрагмент кода, в котором определяется размер документа, он сохраняется в объекте DocSize типа CSize, создается объект клиентской области и определяется ее размер, который сохраняется в объекте ClientRect.

CSize DocSize = GetTotalSize (); RECT ClientRect; GetClientRect (&ClientRect);

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

// если горизонтальная полоса прокрутки видима if (ClientRect.right < DocSize.сx) // передается сообщение ...

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

// если вертикальная полоса прокрутки видима if (ClientRect.bottom < DocSize.cy) // передается сообщение ...

Для изучения механизма обработки сообщения WM_KEYDOWN добавим в программу TextDemo код, позволяющий прокручивать текст, используя и клавиши, и полосы прокрутки, управляемые методами класса CScrollView. Технология создания функции-члена OnKeyDown() класса CTextDemoView, обрабатывающей нажатие клавиш для управления полосой прокрутки, рассмотрена в задании 1.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]