Дата публикации статьи: 10.07.2003 00:00

Ну, что, ребята, может потренируемся? А тренироваться сегодня мы будем настоящей мультимедийной работе с клавиатурой. Написал я эту статью только ради того, чтобы помочь страдающим людям, которые просят меня объяснить им, как можно обрабатывать одновременно несколько клавиш: один пишет аркаду, второй программу, расказывающую о жизни его города, третий ещё сам не решил ...
Начнем с предисловия. Скорее всего, вы уже умеете пользоваться event'ами KeyPress, KeyUp, KeyDown, но, как вы могли убедиться они дают вам возможность обрабатывать только одну одновременно нажатую клавишу. На этом уроке вы научитесь работать с 6-ю, а то и более, одновременно нажатыми клавишами. Это может пригодиться при создании игр и других интерактивных программ. Такую возможность даёт DirectInput (часть мультимедийного пакета DirectX фирмы Microsoft). Естественно, что для начала вам надо его установить. Для работы DirectX с Visual Basic требуется DirectX версии 7(не SDK!) или выше. Скачать его можно абсолютно бесплатно прямо с {сайта Microsoft}. После установки DirectX вы сможете непосредственно приступить к программированию...
Для начала создайте новый проект (Standard EXE). Далее нам надо добавить библиотеки DirectX к вашему проекту. Сделать это вы сможете из меню "Project - References", выбрав из списка "DirectX 7 for Visual Basic Type library" (dx7vb.dll). Теперь приступим к написанию программного кода: добавьте следующие строчки в General Declarations формы:

Dim dx as New DirectX7 'объявляем об использовании DirectX7
Dim di as DirectInput 'объявляем DirectInput
Dim diDEV As DirectInputDevice 'объявляем объект DirectInputDevice
Dim diState As DIKEYBOARDSTATE 'текущее состояние клавиатуры


Добавляем в form_load следующее:

Set di = dx.DirectInputCreate ()

Тут можно вставить ещё обработчик ошибок, чтобы программа не вылетала, если DirectX не установлен или установлена старая версия оного.

DirectInput позволяет работать с клавиатурой, мышью и джойстиком. Но на этом уроке мы рассматриваем только работу с клавиатурой. А по сему мы должны объявить об этом:

Set diDEV = di.CreateDevice("GUID_SysKeyboard")

Теперь нам надо установить формат данных. Т.е. один и тот же формат не может использоваться клавиатурой и джойстиком:

Call didev.SetCommonDataFormat(DIFORMAT_KEYBOARD)

Теперь укажем укажем где использовать DirectInput и установим некоторые параметры работы с клавиатурой:

didev.SetCooperativeLevel Form1.hWnd, DISCL_NONEXCLUSIVE or DISCL_BACKGROUND

Вместо Form1.hWnd может стоять любой объект, события которого мы должны обрабатывать. При работе с клавиатурой можно использовать только не исключительный доступ к клавиатуре (DISCL_NONEXCLUSIVE). Следующий параметр DISCL_BACKGROUND указывает на то, что события будут обрабатываться в любом случае, даже если фокус не на Form1. Абсолютной противоположностью является метод DISCL_FOREGROUND, который выполняет события только при активированной форме.

Теперь активизируем доступ к устройству через метод DirectInputDevice.Acquire:

didev.Acquire ()

!!! Не забудьте поставить didev.UnAcquire в form_unload для избежания проблем при повторном запуске DirectInput. !!!

Теперь нам осталось считать данные с устройства. Для начала объявим следующий массив в General Declarations формы:

Dim aKeys(255) As String
Для распознавания считанных данных с устройства объявим специальную функцию:

Function KeyNames(iNum As Integer) As String

aKeys(1) = "Клавиша ESCAPE"
aKeys(2) = "Клавиша 1 на основной клавиатуре"
aKeys(3) = "Клавиша 2 на основной клавиатуре"
aKeys(4) = "Клавиша 3 на основной клавиатуре"
aKeys(5) = "Клавиша 4 на основной клавиатуре"
aKeys(6) = "Клавиша 5 на основной клавиатуре"
aKeys(7) = "Клавиша 6 на основной клавиатуре"
aKeys(8) = "Клавиша 7 на основной клавиатуре"
aKeys(9) = "Клавиша 8 на основной клавиатуре"
aKeys(10) = "Клавиша 9 на основной клавиатуре"
aKeys(11) = "Клавиша 0 на основной клавиатуре"
aKeys(12) = "Клавиша (-) на основной клавиатуре"
aKeys(13) = "Клавиша (=) на основной клавиатуре"
aKeys(14) = "Клавиша бэкспэйс на основной клавиатуре"
aKeys(15) = "Клавиша TAB"
aKeys(16) = "Клавиша Q"
aKeys(17) = "Клавиша W"
aKeys(18) = "Клавиша E"
aKeys(19) = "Клавиша R"
aKeys(20) = "Клавиша T"
aKeys(21) = "Клавиша Y"
aKeys(22) = "Клавиша U"
aKeys(23) = "Клавиша I"
aKeys(24) = "Клавиша O"
aKeys(25) = "Клавиша P"
aKeys(26) = "Клавиша ["
aKeys(27) = "Клавиша ]"
aKeys(28) = "Клавиша ENTER на основной клавиатуре"
aKeys(29) = "Левый CTRL"
aKeys(30) = "Клавиша A"
aKeys(31) = "Клавиша S"
aKeys(32) = "Клавиша D"
aKeys(33) = "Клавиша F"
aKeys(34) = "Клавиша G"
aKeys(35) = "Клавиша H"
aKeys(36) = "Клавиша J"
aKeys(37) = "Клавиша K"
aKeys(38) = "Клавиша L"
aKeys(39) = "Клавиша ;"
aKeys(40) = "Клавиша '"
aKeys(41) = "Тильда (~)"
aKeys(42) = "Левый SHIFT"
aKeys(43) = "Обратный слэш (/) на основной клавиатуре"
aKeys(44) = "Клавиша Z"
aKeys(45) = "Клавиша X"
aKeys(46) = "Клавиша C"
aKeys(47) = "Клавиша V"
aKeys(48) = "Клавиша B"
aKeys(49) = "Клавиша N"
aKeys(50) = "Клавиша M"
aKeys(51) = "Клавиша COMMA"
aKeys(52) = "Клавиша PERIOD на основной клавиатуре"
aKeys(53) = "Клавиша слэш (/)на основной клавиатуре"
aKeys(54) = "Правый SHIFT"
aKeys(55) = "клавиша (*) на цифровой клавиатуре"
aKeys(56) = "Левый ALT"
aKeys(57) = "Клавиша пробела"
aKeys(58) = "Клавиша CAPS LOCK"
aKeys(59) = "Клавиша F1"
aKeys(60) = "Клавиша F2"
aKeys(61) = "Клавиша F3"
aKeys(62) = "Клавиша F4"
aKeys(63) = "Клавиша F5"
aKeys(64) = "Клавиша F6"
aKeys(65) = "Клавиша F7"
aKeys(66) = "Клавиша F8"
aKeys(67) = "Клавиша F9"
aKeys(68) = "Клавиша F10"
aKeys(69) = "Клавиша NUM LOCK"
aKeys(70) = "Клавиша SCROLL LOCK"
aKeys(71) = "Клавиша NUMPAD7"
aKeys(72) = "Клавиша NUMPAD8"
aKeys(73) = "Клавиша NUMPAD9"
aKeys(74) = "Клавиша (-) на цифровой клавиатуре"
aKeys(75) = "Клавиша NUMPAD4"
aKeys(76) = "Клавиша NUMPAD5"
aKeys(77) = "Клавиша NUMPAD6"
aKeys(78) = "Клавиша (+) на цифровой клавиатуре"
aKeys(79) = "Клавиша NUMPAD1"
aKeys(80) = "Клавиша NUMPAD2"
aKeys(81) = "Клавиша NUMPAD3"
aKeys(82) = "Клавиша NUMPAD0"
aKeys(83) = "Клавиша (/) на цифровой клавиатуре"
aKeys(87) = "Клавиша F11"
aKeys(88) = "Клавиша F12"
aKeys(86) = "Клавиша F13"
aKeys(84) = "Клавиша F14"
aKeys(85) = "Клавиша F15"
aKeys(156) = "Клавиша 5 на цифровой клавиатуре"
aKeys(157) = "CTRL левый"
aKeys(91) = "Comma на NEC PC98 цифровой клавиатуре"
aKeys(181) = "Обратный слэш (/) на цифровой клавиатуре"
aKeys(183) = "Клавиша Print Screen"
aKeys(184) = "ALT правый"
aKeys(199) = "Клавиша Home"
aKeys(200) = "Клавиша Up"
aKeys(201) = "Клавиша Page Up"
aKeys(203) = "Клавиша Left"
aKeys(205) = "Клавиша Right"
aKeys(207) = "Клавиша End"
aKeys(208) = "Клавиша Down"
aKeys(209) = "Клавиша Page Down"
aKeys(210) = "Клавиша Insert"
aKeys(211) = "Клавиша Delete"
aKeys(219) = "Левая Windows'кая клавиша (только для Windows клавиатуры)"
aKeys(220) = "Правая Windows'кая клавиша (только для Windows клавиатуры)"
aKeys(221) = "Клавиша Application(только для Windows клавиатуры)"
aKeys(116) = "Клавиша Пауза"


KeyNames = aKeys(iNum)

End Function

Завершающая стадия - обработка результатов. Для этого нам потребуется один лист-бокс и один таймер. Создадим их. Назовём лист-бокс - lstKeys, а таймер - tmrKeys. Интервал таймера по вашему усмотрению. Перед редактированием кода таймера вставим данный код в General Declaration формы:

Dim iKeyCounter As Integer 'для того, чтобы значение iKeyCounter при работе таймера не сбрасывалось каждый раз

Сам код таймера:

Private Sub tmrKeys_Timer()
lstKeys.Clear 'очистка lstkeys происходит для того, чтобы отображать только нажатые в данный момент клавиши.

diDEV.GetDeviceStateKeyboard diState 'очень важная часть - узнаем у DirectInputDevice текущий статус клавиатуры.


For iKeyCounter = 0 To 255 'обрабатываем все возможные клавиши
If diState.Key(iKeyCounter) <> 0 Then 'если клавиша № iKeyCounter из функции KeyNames нажата
lstKeys.AddItem KeyNames(iKeyCounter) 'добавляем её описание в lstKeys
End If
Next
DoEvents
End Sub