Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_I.pdf
Скачиваний:
96
Добавлен:
05.06.2014
Размер:
4.61 Mб
Скачать

173

клавиши переключения, функциональные клавиши, клавиши управления курсором и специальные клавиши, такие как Insert и Delete. Для таких клавиш Windows вырабатывает только аппаратные сообщения.

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

Когда вы нажимаете клавишу, Windows помещает либо сообщение WM_KEYDOWN, либо сообщение WM_SYSKEYDOWN в очередь сообщений окна, имеющего фокус ввода. Когда вы отпускаете клавишу, Windows помещает либо сообщение WM_KEYUP, либо сообщение WM_SYSKEYUP в очередь сообщений.

 

Клавиша нажата

Клавиша отпущена

Несистемные аппаратные сообщения

WM_KEYDOWN

WM_KEYUP

Системные аппаратные сообщения

WM_SYSKEYDOWN

WM_SYSKEYUP

Обычно сообщения о "нажатии" (down) и "отпускании" (up) появляются парами. Однако, если вы оставите клавишу нажатой так, чтобы включился автоповтор, то Windows посылает оконной процедуре серию сообщений

WM_KEYDOWN (или WM_SYSKEYDOWN) и одно сообщение WM_KEYUP (или WM_SYSKEYUP), когда в конце концов клавиша будет отпущена. Также как и все синхронные сообщения, аппаратные сообщения клавиатуры также становятся в очередь. Вы можете с помощью функции GetMessageTime получить время нажатия и отпускания клавиши относительно старта системы.

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

Префикс "SYS" в WM_SYSKEYDOWN и WM_SYSKEYUP означает "системное" (system) и относится к аппаратным сообщениям клавиатуры, которые больше важны для Windows, чем для приложений Windows. Сообщения WM_SYSKEYDOWN и WM_SYSKEYUP обычно вырабатываются при нажатии клавиш в сочетании с клавишей <Alt>. Эти сообщения вызывают опции меню программы или системного меню, или используются для системных функций, таких как смена активного окна (<Alt>+<Tab> или <Alt>+<Esc>), или как быстрые клавиши системного меню (<Alt> в сочетании с функциональной клавишей). Программы обычно игнорируют сообщения WM_SYSKEYDOWN и WM_SYSKEYUP и передают их DefWindowProc. Поскольку Windows отрабатывает всю логику Alt-клавиш, то вам фактически не нужно обрабатывать эти сообщения. Ваша оконная процедура в конце концов получит другие сообщения, являющиеся результатом этих аппаратных сообщений клавиатуры (например, выбор меню). Если вы хотите включить в код вашей оконной процедуры инструкции для обработки аппаратных сообщений клавиатуры (как мы это сделаем в программе KEYLOOK, представленной далее в этой главе), то после обработки этих сообщений передайте их в DefWindowProc, чтобы Windows могла по-прежнему их использовать в обычных целях.

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

case WM_SYSKEYDOWN; case WM_SYSKEYUP; case WM_SYSCHAR;

return 0;

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

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

Переменная lParam

Для всех аппаратных сообщений клавиатуры, 32-разрядная переменная lParam, передаваемая в оконную процедуру, состоит из шести полей: счетчика повторений (Repeat Count), cкан-кода OEM (Original Equipment Manufacturer Scan Code), флага расширенной клавиатуры (Extended Key Flag), кода контекста (Context Code), флага предыдущего состояния клавиши (Previous Key State) и флага состояния клавиши (Transition State). (См. рис. 5.1)

174

Extended Key Flag

 

 

Context Code

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

16-Bit

 

 

 

 

 

 

 

 

 

 

Previos Key State

 

 

 

 

 

Repeat Count

 

 

 

8-Bit O EM

 

 

 

 

 

 

 

 

 

 

 

 

Scan Code

 

 

 

 

 

 

 

 

Transition State

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 5.1 Шесть полей переменной lParam аппаратных сообщений клавиатуры

Счетчик повторений

Счетчик повторений равен числу нажатий клавиши, которое отражено в сообщении. В большинстве случаев он устанавливается в 1. Однако, если клавиша остается нажатой, а ваша оконная процедура недостаточно быстра, чтобы обрабатывать эти сообщения в темпе автоповтора (по умолчанию это приблизительно 10 символов в секунду), то Windows объединяет несколько сообщений WM_KEYDOWN или WM_SYSKEYDOWN в одно сообщение и соответственно увеличивает счетчик повторений. Для сообщения WM_KEYUP или WM_SYSKEYUP счетчик повторений всегда равен 1.

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

Скан-код OEM

Скан-код OEM является кодом клавиатуры, генерируемым аппаратурой компьютера. (Если вы хорошо знакомы с программированием на языке ассемблера, то скан-код — это код, передаваемый программе в регистре AH при вызове прерывания 16H BIOS.) Приложения Windows обычно игнорируют скан-код OEM, поскольку имеют более совершенные способы расшифровки информации от клавиатуры.

Флаг расширенной клавиатуры

Флаг расширенной клавиатуры устанавливается в 1, если сообщение клавиатуры появилось в результате работы с дополнительными клавишами расширенной клавиатуры IBM. (Расширенная клавиатура IBM имеет функциональные клавиши сверху и отдельную комбинированную область клавиш управления курсором и цифр.) Этот флаг устанавливается в 1 для клавишей <Alt> и <Ctrl> на правой стороне клавиатуры, клавиш управления курсором (включая <Insert> и <Delete>), которые не являются частью числовой клавиатуры, клавиш наклонной черты (</>) и <Enter> на числовой клавиатуре и клавиши <NumLock>. Программы для Windows обычно игнорируют флаг расширенной клавиатуры.

Код контекста

Код контекста устанавливается в 1, если нажата клавиша <Alt>. Этот разряд всегда равен 1 для сообщений

WM_SYSKEYDOWN и WM_SYSKEYUP и 0 для сообщений WM_KEYDOWN и WM_KEYUP с двумя исключениями:

Если активное окно минимизировано, оно не имеет фокус ввода. Все нажатия клавиш вырабатывают сообщения WM_SYSKEYDOWN и WM_SYSKEYUP. Если не нажата клавиша <Alt>, поле кода контекста устанавливается в 0. (Windows использует SYS сообщения клавиатуры так, чтобы активное окно, которое минимизировано, не обрабатывало эти сообщения.)

На некоторых иноязычных клавиатурах некоторые символы генерируются комбинацией клавиш <Shift>, <Ctrl> или <Alt> с другой клавишей. В этих случаях, у переменной lParam, которая сопровождает сообщения WM_KEYDOWN и WM_KEYUP, в поле кода контекста ставится 1, но эти сообщения не являются системными сообщениями клавиатуры.

175

Флаг предыдущего состояния клавиши

Флаг предыдущего состояния клавиши равен 0, если в предыдущем состоянии клавиша была отпущена, и 1, если в предыдущем состоянии она была нажата. Он всегда устанавливается в 1 для сообщения WM_KEYUP или WM_SYSKEYUP, но для сообщения WM_KEYDOWN или WM_SYSKEYDOWN он может устанавливаться как в 1, так и в 0. В этом случае 1 показывает наличие второго и последующих сообщений от клавиш в результате автоповтора.

Флаг состояния клавиши

Флаг состояния клавиши равен 0, если клавиша нажимается, и 1, если клавиша отпускается. Это поле устанавливается в 0 для сообщения WM_KEYDOWN или WM_SYSKEYDOWN и в 1 для сообщения WM_KEYUP

или WM_SYSKEYUP.

Виртуальные коды клавиш

Хотя некоторая информация в lParam при обработке сообщений WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP и WM_SYSKEYDOWN может оказаться полезной, гораздо более важен параметр wParam. В этом параметре содержится "виртуальный код клавиши" (virtual key code), идентифицирующий нажатую или отпущенную клавишу. Разработчики Windows попытались определить виртуальные клавиши независимым от аппаратуры способом. По этой причине, некоторые виртуальные коды клавиш не могут вырабатываться на персональных компьютерах IBM и совместимых с ними, но их можно встретить на клавиатурах других производителей.

Виртуальные коды клавиш, которые вы используете, наиболее часто имеют имена, определенные в заголовочных файлах Windows. В показанной ниже таблице представлены эти имена, числовые коды клавиш, а также клавиши персональных компьютеров IBM, соответствующие виртуальным клавишам. Хотя все клавиши вызывают аппаратные сообщения клавиатуры, в таблицу не включены клавиши символов (например, клавиши символов / или ?). Эти клавиши имеют виртуальные коды от 128 и выше, и они в международных клавиатурах часто определяются по-другому. Вы можете определить значения этих виртуальных кодов клавиш с помощью программы KEYLOOK, представленной далее в этой главе, но обычно вам не нужно обрабатывать аппаратные сообщения клавиатуры для этих клавиш.

 

 

 

 

Виртуальные коды клавиш

Деся-

Шестнадца-

WINDOWS.H

Требу-

Клавиатура IBM

 

тичное

теричное

Идентификатор

ется

 

 

1

01

VK_LBUTTON

2

02

VK_RBUTTON

3

03

VK_CANCEL

4

04

VK_MBUTTON

8

08

VK_BACK

9

09

VK_TAB

12

0C

VK_CLEAR

13

0D

VK_RETURN

16

10

VK_SHIFT

17

11

VK_CONTROL

18

12

VK_MENU

19

13

VK_PAUSE

20

14

VK_CAPITAL

27

1B

VK_ESCAPE

32

20

VK_SPACE

33

21

VK_PRIOR

34

22

VK_NEXT

35

23

VK_END

36

24

VK_HOME

37

25

VK_LEFT

38

26

VK_UP

39

27

VK_RIGHT

40

28

VK_DOWN

41

29

VK_SELECT

42

2A

VK_PRINT

43

2B

VK_EXECUTE

44

2C

VK_SNAPSHOT

45

2D

VK_INSERT

Ctrl-Break

Backspace

Tab

5 на дополнительной цифровой клавиатуре при отключенном

Num Lock

Enter

Shift

Ctrl

Alt Pause

Caps Lock

Esc

Пробел (Spacebar)

Page Up

Page Down End

Home

Стрелка влево

Стрелка вверх

Стрелка вправо

Стрелка вниз

Print Screen

Insert

176

Деся-

Шестнадца-

WINDOWS.H

Требу-

Клавиатура IBM

тичное

теричное

Идентификатор

ется

 

46

2E

VK_DELETE

 

Delete

47

2F

VK_HELP

 

 

48-57

30-39

 

От 0 до 9 на

65-90

41-5A

 

 

основной клавиатуре

 

От A до Z

96

60

VK_NUMPAD0

 

0 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

97

61

VK_NUMPAD1

 

1 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

98

62

VK_NUMPAD2

 

2 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

99

63

VK_NUMPAD3

 

3 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

100

64

VK_NUMPAD4

 

4 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

101

65

VK_NUMPAD5

 

5 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

102

66

VK_NUMPAD6

 

6 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

103

67

VK_NUMPAD7

 

7 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

104

68

VK_NUMPAD8

 

8 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

105

69

VK_NUMPAD9

 

9 на дополнительной

 

 

 

 

цифровой клавиатуре

 

 

 

 

при включенном Num

 

 

 

 

Lock

106

6A

VK_MULTIPLY

 

* на дополнительной

 

 

 

 

цифровой клавиатуре

107

6B

VK_ADD

 

+ на дополнительной

108

6C

VK_SEPARATOR

 

цифровой клавиатуре

 

 

109

6D

VK_SUBTRACT

 

- на дополнительной

 

 

 

 

цифровой клавиатуре

110

6E

VK_DECIMAL

 

. на дополнительной

 

 

 

 

цифровой клавиатуре

111

6F

VK_DIVIDE

 

/ на дополнительной

112

70

VK_F1

 

цифровой клавиатуре

Функциональная

113

71

VK_F2

 

клавиша F1

Функциональная

114

72

VK_F3

 

клавиша F2

Функциональная

115

73

VK_F4

 

клавиша F3

Функциональная

116

74

VK_F5

 

клавиша F4

Функциональная

117

75

VK_F6

 

клавиша F5

Функциональная

177

Деся-

Шестнадца-

WINDOWS.H

Требу-

Клавиатура IBM

 

тичное

теричное

Идентификатор

ется

 

 

118

76

VK_F7

 

клавиша F6

 

Функциональная

 

119

77

VK_F8

 

клавиша F7

 

Функциональная

 

120

78

VK_F9

 

клавиша F8

 

Функциональная

 

121

79

VK_F10

 

клавиша F9

 

Функциональная

 

 

 

 

 

клавиша F10

 

122

7A

VK_F11

 

Функциональная

 

 

 

 

 

клавиша

F11

 

 

 

 

(расширенная

 

 

 

 

 

клавиатура)

 

123

7B

VK_F12

 

Функциональная

 

 

 

 

 

клавиша

F12

 

 

 

 

(расширенная

 

124

7C

VK_F13

 

клавиатура)

 

 

 

 

125

7D

VK_F14

 

 

 

126

7E

VK_F15

 

 

 

127

7F

VK_F16

 

 

 

144

90

VK_NUMLOCK

 

Num Lock

 

145

91

VK_SCROLL

 

Scroll Lock

 

Пометка ( ) в столбце "Требуется" показывает, что клавиша предопределена для любой реализации Windows. Windows также требует, чтобы клавиатура и драйвер клавиатуры позволяли комбинировать клавиши <Shift>, <Ctrl>, а также <Shift> и <Ctrl> вместе, со всеми буквенными клавишами, всеми клавишами управления курсором и всеми функциональными клавишами. Виртуальные коды клавиш VK_LBUTTON, VK_MBUTTON и VK_RBUTTON относятся к левой, центральной и правой кнопкам мыши. Однако, вам никогда не удастся получить сообщения клавиатуры с параметром wParam, в котором установлены эти значения. Мышь, как мы увидим в следующей главе, вырабатывает свои собственные сообщения.

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

Параметры wParam и lParam сообщений WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP и WM_SYSKEYDOWN ничего не сообщают вашей программе о положении клавиш сдвига и клавишпереключателей. Вы можете получить текущее состояние любой виртуальной клавиши с помощью функции GetKeyState. Эта функция в основном используется для получения информации о состоянии клавиш сдвига

(<Shift>, <Ctrl> и <Alt>) и клавиш-переключателей (<CapsLock>, <NumLock> и <ScrollLock>). Например:

GetKeyState(VK_SHIFT);

возвращает отрицательное значение (т. е., установлен старший разряд), если клавиша <Shift> нажата. В возвращаемом функцией:

GetKeyState(VK_CAPITAL);

значении установлен младший разряд, если переключатель <CapsLock> включен. Вы также можете получить положение кнопок мыши с помощью виртуальных кодов клавиш VK_LBUTTON, VK_MBUTTON и VK_RBUTTON. Однако, большая часть программ для Windows, которым надо отслеживать сочетание состояний кнопок мыши и клавиш клавиатуры, делают это другим способом — проверяя состояние клавиш клавиатуры при получении сообщения от мыши. Фактически, информация о положении клавиш сдвига и клавиш-переключателей включается в сообщения от мыши (как вы увидите в следующей главе).

Будьте осторожны с функцией GetKeyState. Она не отражает положение клавиатуры в реальном времени. Она отражает состояние клавиатуры на момент, когда последнее сообщение от клавиатуры было выбрано из очереди. Функция GetKeyState не позволяет вам получать информацию о клавиатуре, независимо от обычных сообщений клавиатуры. Например, вы захотите, чтобы процесс обработки сообщения в оконной процедуре продолжался до тех пор, пока пользователь не нажмет функциональную клавишу <F1>:

while(GetKeyState(VK_F1) >= 0); // ОШИБКА!!!

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

Соседние файлы в предмете Операционные системы