Коды клавиш клавиатуры delphi
Коды клавиш клавиатуры delphi
Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.2.2005
Репутация: нет
Всего: нет
выложите здесь коды клавиатурных клавиш или дайте ссылку!
или скажите почему когда я пробую для теста проверять клавиши:
при событии формы OnKeyPress
if Key=#13 then
Form1.Close;
if Key=Chr(vk_Up) then
Form1.Close;
может че не так
Лентяй 2
Профиль
Группа: Админ
Сообщений: 1993
Регистрация: 12.5.2004
Репутация: 31
Всего: 155
Что есть vk_Up?
Бывалый
Профиль
Группа: Участник
Сообщений: 215
Регистрация: 24.2.2005
Репутация: нет
Всего: нет
Vk_up это клавиша вверх.
F1 112 $70 VK_F1
F2 113 $71 VK_F2
F3 114 $72 VK_F3
F4 115 $73 VK_F4
F5 116 $74 VK_F5
F6 117 $75 VK_F6
F7 118 $76 VK_F7
F8 119 $77 VK_F8
F9 120 $78 VK_F9
F10 121 $79 VK_F10
пробел 32 $20 VK_SPACE
BackSpace 8 $8 VK_BACK
Tab 9 $9 VK_TAB
Enter 13 $0D VK_RETURN
Shift 16 $10 VK_SHIFT
Ctrl 17 $11 VK_CONTROL
Alt 18 $12 VK_MENU
CapsLock 20 $14 VK_CAPITAL
Esc 27 $1B VK_ESCAPE
Insert 45 $2D VK_INSERT
PageUp 33 $21 VK_PRIOR
PageDown 34 $22 VK_NEXT
End 35 $23 VK_END
Home 36 $24 VK_HOME
37 $25 VK_LEFT
38 $26 VK_UP
39 $27 VK_RIGHT
40 $28 VK_DOWN
Delete 46 $2E VK_DELETE
PrintScreen 44 $2C VK_SNAPSHOT
ScrollLock 145 $91 VK_SCROLL
Pause 19 $13 VK_PAUSE
NumLock 144 $90 VK_NUMLOCK
0,) 48 $30 ord(‘0’)
1 ! 49 $31 ord(‘1’)
2 @ 50 $32 ord(‘2’)
3 # 51 $33 ord(‘3’)
4 $ 52 $34 ord(‘4’)
5 % 53 $35 ord(‘5’)
6 ^ 54 $36 ord(‘6’)
7 & 55 $37 ord(‘7’)
8 * 56 $38 ord(‘8’)
9 ( 57 $39 ord(‘9’)
`
192 $C0
— _ 189 $BD
= + 187 $BB
[ < 219 $DB
] > 221 $DD
; : 186 $BA
‘ » 222 $DE
| 220 $DC
, 190 $BE
/ ? 191 $BF
a,A 65 $41 ord(‘A’)
b,B 66 $42 ord(‘B’)
c,C 67 $43 ord(‘C’)
d,D 68 $44 ord(‘D’)
e,E 69 $45 ord(‘E’)
f,F 70 $46 ord(‘F’)
g,G 71 $47 ord(‘G’)
h,H 72 $48 ord(‘H’)
i,I 73 $49 ord(‘I’)
j,J 74 $4A ord(‘J’)
k,K 75 $4B ord(‘K’)
l,L 76 $4C ord(‘L’)
m,M 77 $4D ord(‘M’)
n,N 78 $4E ord(‘N’)
o,O 79 $4F ord(‘O’)
p,P 80 $50 ord(‘P’)
q,Q 81 $51 ord(‘Q’)
r,R 82 $52 ord(‘R’)
s,S 83 $53 ord(‘S’)
t,T 84 $54 ord(‘T’)
u,U 85 $55 ord(‘U’)
v,V 86 $56 ord(‘V’)
w,W 87 $57 ord(‘W’)
x,X 88 $58 ord(‘X’)
y,Y 89 $59 ord(‘Y’)
z,Z 90 $5A ord(‘Z’)
На правой клавиатуре при выключенной NumLock
0 96 $60 VK_NUMPAD0
1 97 $61 VK_NUMPAD1
2 98 $62 VK_NUMPAD2
3 99 $63 VK_NUMPAD3
4 100 $64 VK_NUMPAD4
5 101 $65 VK_NUMPAD5
6 102 $66 VK_NUMPAD6
7 103 $67 VK_NUMPAD7
8 104 $68 VK_NUMPAD8
9 105 $69 VK_NUMPAD9
* 106 $6A VK_MULTIPLY
+ 107 $6B VK_ADD
— 109 $6D VK_SUBTRACT
. 110 $6E VK_DECIMAL
/ 111 $6F VK_DIVIDE
Delphi 2010. Работа с клавиатурой в условиях Unicode.
Как я уже отмечал, начиная с Delphi 2009 введена полная поддержка Unicode. Это замечательно, необходимо и важно. Однако, как ни крути, но не все толком понимают как работать-то? Я сейчас не имею ввиду профессиональных программистов, работающих постоянно с Delphi. Речь идёт о простых любителях, начинающих программистах, которые большую часть информации получают из Сети, в результате чего возникают всякие непредвиденные ситуации. Вот, например, ситуация — надо написать программу, которая будет отлавливать нажатия клавиш клавиатуры и записывать их в лог. В Интернет есть масса примеров как организовать глобальный хук на клаву и считывать в лог виртуальные и скан-коды клавиш (подобная статья есть и у нас в блоге). Естественно, начинающий программист просто качает готовый пример и пробует транслировать эти самые коды в буковки…а они просто так не транслируются — получаем либо «кракозябры» либо нормальные буквы но не те. И сидит такой начинающий программист, чешет затылок и другие части тела, не понимая что он делает не так? В лучшем случае лезет в опять в Сеть и с огромной вероятностью натыкается на подобного рода «рецепты-объяснения»:
В событиях OnKeyDown и OnKeyUp, Key является беззнаковым двухбайтовым (Word) значением, которое представляет виртуальную клавишу Windows. Для получания значения символа можно воспользоваться функцией Chr. В событии OnKeyPress параметр Key является значением Char, которое представляет символ ASCII.
Вроде все правильно. НО не для Delphi 2009-2010, при работе с русскими символами, так как во-первых, введена поддержка Unicode, а во-вторых ASCII никогда с роду не содержала русских букв (см.историю разработки кодировок). И никогда, ни при каких обстоятельствах Вы не сможете перевести просто так виртуальную клавишу в русский символ функцией Chr.
Если не верите — проделайте такой простой эксперимент: откройте Delphi 2009-2010, создайте новое приложение и в событии onKeyUp для главной формы напишите такой код:
Теперь запустите приложение, переключитесь на русский язык и нажмите любую клавишу.
Вот результат нажатия русской буквы «Ы»:
Спрашивается: Чё за фигня? Где моя буковка «Ы»? И, что самое интересное, я ведь нажимал букву без Shift и CapsLock, а мне чего-то буква в верхнем регистре упала? Давайте разбираться в определениях. Так как без четкого знания определений мы с Вами в этих лабиринтах и хитросплетениях не разберемся никогда.
1. Скан-коды, виртуальные код и коды символов
Итак, с клавиатурой связано как минимум три разновидности кодов: скан-код, символьный код и виртуальный код. И далеко не все начинающие программисты понимают различия между ними.
Самая большая путаница со скан-кодами. Для начала, их существует две разновидности. Есть скан-коды «настоящие» — это то, что получает система прямо от клавиатуры, а есть скан-коды которые выдаются после того, как они будут обработаны в BIOS, которая интерпретирует, например, одновременное нажатие клавиш-модификаторов, а также справляется с текущей таблицей кодов символов и отправляет эти скан-коды в буфер клавиатуры.
Теперь посмотрим, как выглядит скан-код в принципе. На рисунке представлена оригинальная 84-кнопочная клавиатура IBM PC. Вот во времена существования этой клавиатуры и назначались скан-коды клавишам. Причем присваивались они слева-направо, начиная с клавиши Esc. Так клавиша Esc получила скан-код 1, а клавиша 1 — код 2 и т.д. Пока не будем кидаться в дебри дополнительных клавиш, которые появились на современных клавиатурах (там есть свои особенности присвоения скан-кодов), а уясним для себя следующее:
Скан-код — это идентификатор клавиши на клавиатуре и он один в чистом виде никак не может сам по себе описать символ в условиях unicode
Теперь двигаемся дальше. Разберемся с виртуальными кодами.
Виртуальные коды — это то, что использует система (Windows) для идентификации клавиш.
То есть, проведя простую аналогию, можно с большим допущением сказать, что виртуальный код клавиши — это тот же скан-код, но только не для BIOS, а для операционной системы, установленной на компьютере пользователя.
С некоторыми из констант, определяющих виртуальный код клавиш Вы можете ознакомиться в модуле windows.pas Delphi. Но, там отсутствуют коды для буквенно-цифровых клавиш, т.к. они совпадают с соответствующими символами из таблицы ASCII .
Теперь, я думаю, становится более-менее ясно почему при нажатии клавиши с буквой «ы» мы в примере получили заглавную букву «S»? Delphi в этом случае сработала идеально правильно — выдала именно виртуальный код клавиши, как и полагается.
А для того, чтобы получить русскую букву нам необходимо знать третий код — код символа в таблице символов Unicode или, как мы посмотрим ниже, скан-код, виртуальный код и ещё один параметр — состояние клавиатуры.
Для того, чтобы продемонстрировать правильность работы Delphi, немного допишем наш пример.
Коды клавиш клавиатуры delphi
Delphi уже давно (если быть точным – с версии 2009) поддерживает UNICODE, но, по непонятным для меня причинам, до сих пор (а на пороге уже Delphi XE8) не «научила» компоненты, предназначенные для редактирования текста, воспринимать Alt-коды, вводимые с клавиатуры, хотя из кода это можно сделать без каких либо проблем. Ввод символа ≠ из кода можно реализовать, например, так:
Хотелось бы иметь возможность вводить подобные символы с клавиатуры, как, например, это позволяет делать MS Word. В этой статье я хочу показать, как можно исправить это досадное упущение.
В начале несколько слов для тех, кто не знаком с Alt-кодами. ALT-код — код, символы которого вводятся посредством кнопки Alt и последовательности цифр на NUM-паде (небольшом блоке из 17 клавиш, обычно находящемся с правого края клавиатуры). Так, для того, чтобы ввести символ ‘≠’, нужно нажать кнопку Alt , и не отпуская ее нажать на NUM-паде последовательность цифр 8 + 8 + 0 + 0 .
Очевидно, что для решения этой задачи нам нужно перехватывать нажатие клавиши Alt , запоминать последовательность цифр, введенных с NUM-пад (при нажатой кнопке Alt ), а при отпускании клавиши Alt вставлять в текст символ, соответствующий введенному коду. Это наводит на мысль о необходимости использования клавиатурного хука.
Мы можем воспользоваться одним из 2 вариантов, а именно WH_KEYBOARD или WH_KEYBOARD_LL. Если кратко описать разницу между ними, то можно сказать так: WH_KEYBOARD срабатывает при попадании в очередь сообщений потока сообщений WM_KEYUP/WM_KEYDOWN, а WH_KEYBOARD_LL срабатывает при низкоуровневых клавиатурных событиях, поступающих от драйвера клавиатуры (процедура обработки WH_KEYBOARD_LL выполняется в контексте приложения, установившего хук).
Рассмотрим оба варианта, и начнем с WH_KEYBOARD.
WH_KEYBOARD
Если у вас возник вопрос, почему для хранения введенного пользователем кода используется локальная константа, и как это вообще работает, прочтите статью Константы в Delphi, а здесь я повторяться не стану. Теперь рассмотрим параметры процедуры хука:
- Code – может принимать одно из следующих значений:
- HC_ACTION – приходит при удалении сообщения из очереди;
- HC_NOREMOVE – приходит, когда клавиатурное сообщение не удаляется из очереди, потому что приложение вызвало функцию PeekMessage с параметром PM_NOREMOVE. При вызове хука с этим кодом не гарантируется передача действительного состояния клавиатуры;
- wParam – содержит виртуальный код клавиши (например, VK_F1, VK_RETURN, VK_LEFT);
- lParam расшифровывается следующим образом:
- Биты 0-15 содержат количество повторений нажатой клавиши в случае «залипания»;
- Биты 16-23 содержат скан код нажатой клавиши. Это аппаратно зависимый код, который зависит от конкретной клавиатуры;
- Бит 24 равен 1, если нажатая клавиша является расширенной (функциональной или на цифровой клавиатуре), иначе 0;
- Биты 25-28 зарезервированы;
- Бит 29 равен 1, если при нажатии клавиши была нажата клавиша Alt , иначе 0;
- Бит 30 говорит о состоянии клавиши до отправки сообщения. Бит равен 1, если до этого кнопка отправки сообщения была нажата, иначе 0;
- Бит 31 говорит о текущем состоянии клавиши. Он равен 1, если клавиша отпускается, иначе 0.
Первое, что нужно определить – нажата ли клавиша Alt. Это можно сделать несколькими способами. Рассмотрим их:
Если клавиша Alt нажата, запоминает вводимые с NUM-пада цифры, формируя из них строку. При отпускании клавиши Alt заносим символ, соответствующий введенному коду, в текстовое поле в позицию каретки или заменяя выделенный текст. Обратите внимание на то, что для работы 3-его примера переменная IsAltDown должна быть глобальной, в то время как для первых 2-х премеров это не обязательно.
Теперь рассмотрим вариант с WH_KEYBOARD_LL.
WH_KEYBOARD_LL
Рассмотрим параметры структуры TKbdDllHookStrukt:
- vkCode – виртуальный код клавиши;
- scanCode – скан-код нажатой клавиши. Это аппаратно зависимый код, который зависит от конкретной клавиатуры;
- flags — расшифровывается следующим образом:
- Бит 0 равен 1, если нажатая клавиша является расширенной (функциональной или на цифровой клавиатуре), иначе 0;
- Бит 1 равен 1, если сообщение пришло от Low Level Integrity процесса, иначе 0;
- Биты 2 и 3 зарезервированы;
- Бит 4 равен 1, если это внедренное (injected) событие, иначе 0;
- Бит 5 равен 1, если при нажатии клавиши была нажата клавиша Alt , иначе 0;
- Бит 6 зарезервирован;
- Биты 7 говорит о текущем состоянии клавиши. Он равен 1, если клавиша отпускается, иначе 0.
- time – время отправки сообщения;
- dwExtraInfo – дополнительная информация, связанная с сообщением.
Принцип действия аналогичен примеру на WH_KEYBOARD, за исключением того, что для запоминания введенного числового кода используется не строка, а числовая переменная. Какой именно способ использовать, зависит от ваших личных предпочтений.
Полные исходные коды находятся в примерах к данной статье. В примерах поддержка Alt-кодов показана на примере компонента TEdit, однако этот метод можно применить к любым другим компонентам редактирования текста.
OnKeyDown, OnKeyUp и OnKeyPress
Симфония на клавиатуре(статья)
Содержание материала
Перевод одноимённой статьи с сайта delphi.about.com )
Начиная с самого рассвета компьютерной промышленности, клавиатура была первичным устройством ввода информации, и вероятнее всего сохранит свою позицию ещё долгое время.
События клавиатуры, наряду с событиями мыши, являются основными элементами взаимодействия пользователя с программой. В данной статье пойдёт речь о трёх событиях, которые позволяют отлавливать нажатия клавиш в приложении Delphi: OnKeyDown , OnKeyUp и OnKeyPress .
Для получения ввода с клавиатуры, приложения Delphi могут использовать два метода. Самый простой способ, это воспользоваться одним из компонентов, автоматически реагирущем на нажатия клавиш, таким как Edit. Второй способ заключается в создании процедур в форме, которые будут обрабатывать нажатия и отпускания клавиш. Эти обработчики могут обрабатывать как нажатия одиночных клавиш, так и комбинаций. Итак, вот эти события:
OnKeyDown — вызывается, когда на клавиатуре нажимается любая клавиша. OnKeyUp — вызывается, когда любая клавиша на клавиатуре отпускается. OnKeyPress — вызывается, когда нажимается клавиша, отвечающая за определённый ASCII символ.
Теперь самое время посмотреть, как выглядят в программе заголовки обработчиков:
(Sender: TObject; var Key: Word; Shift: TShiftState);
(Sender: TObject; var Key: Word; Shift: TShiftState);
(Sender: TObject; var Key: Char);
Все события имеют один общий параметр, обычно называемый Key . Этот параметр используется для передачи кода нажатой клавиши. Параметр Shift (в процедурах OnKeyDown и OnKeyUp), указывает на то, была ли нажата клавиша в сочетании с Shift , Alt , и Ctrl .
Фокус, это способность получать пользовательский ввод через мышь или клавиатуру. Получать события от клавиатуры могут только те объекты, которые имеют фокус. На форме активного приложения в один момент времени может быть активным (иметь фокус) только один компонент.
Некоторые компоненты, такие как TImage, TPaintBox, TPanel и TLabel не могут получать фокус, другими словами, это компоненты, наследованные от TGraphicControl. Так же не могут получать фокус невидимые компоненты, такие как TTimer.
События OnKeyDown и OnKeyUp обеспечивают самый низкий уровень ответа клавиатуры. Обработчики OnKeyDown и OnKeyUp могут реагировать на все клавиши клавиатуры, включая функциональные и комбинации с клавишами Shift, Alt, и Ctrl.
События клавиатуры — не взаимоисключающие. Когда пользователь нажимает клавишу, то генерируются два события OnKeyDown и OnKeyPress, а когда отпускает, то только одно: OnKeyUp. Если пользователь нажмёт одну из клавиш, которую OnKeyPress не сможет определить, то будет сгенерировано только одно событие OnKeyDown, а при отпускании OnKeyUp.
OnKeyPress возвращает различные значения ASCII для ‘g’ и ‘G,’. Однако, OnKeyDown и OnKeyUp не делают различия между верхним и нижним регистром.
Параметры Key и Shift
Параметр Key можно изменять, чтобы приложение получило другой код нажатой клавиши. Таким образом можно ограничивать набор различных символов, которые пользователь может ввести с клавиатуры. Например разрешить вводить только цифры. Для этого добавьте в обработчик события OnKeyPress следующий код и установите KeyPreview в True (см. ниже).
Коды клавиш клавиатуры delphi
Dikoy
Вроде, скан кода 0 в таблице нет, что намекает.
Когда-то читал, что скан код 0 означает переполнение буфера клавиатуры.
Посмотрите первую ссылку в гугле на keyboard scancode specification. У меня на работе слово microsoft в бане, сейчас посмотреть не могу.
Dikoy
Описаны скан коды клавиш, но не комбинаций. Как происходит передача комбинаций клавиш нигде толком не описано.
Нет комбинаций. Только нажатие каждой и отпускание. Комбинирование происходит внутри компа.
Но найти бы документальное подтверждение.
Уже давно бы подключил осциллоскоп и посмотрел. Если есть LPT порт, то 3 проводка и программа логического анализатора тоже сразу всё прояснили бы.
На странице из педивикии внизу есть ссылки, четвёртая из которых ведёт к более подробному описанию клавиатуры. И там, в частности, есть таблица скан кодов. В этой таблице в каждой ячейке приведено значение основного значения клавиши и с шифтом, что и означает, что независимо от нажатых клавиш-модификаторов, скан код один и тот же.
Индикаторы ScrollLock, NumLock и CapsLock вообще могут управляться отдельно.
цитата: Клавиатура XT — 83 клавиши, в оригинале без индикаторов. Впоследствии к ним добавили индикаторы состояния NumLock и CapsLock, управляемые внутренним контроллером по нажатию соответствующих клавиш. Однако состояние этих индикаторов могло не быть синхронизированным с флагами в ОЗУ, которыми пользуются драйверы.
Клавиатура AT- 84 клавиши, которая отличалась от XT появлением дополнительной клавиши SYSREQ загадочного назначения и индикаторов Num Lock, Caps Lock, Scroll Lock. Двунаправленный интерфейс с системной платой позволяет программе корректно управлять индикаторами, а также программировать некоторые параметры клавиатуры и производить диагностику.
Vesel’chak U
Уже давно бы подключил осциллоскоп и посмотрел.
С USBишной клавиатурой не так элементарно.
Описание устарело. Старые(PC/XT) клавиатуры передавали однобайтовые сканкоды, а современные ещё и двубайтовые.
Tor Bel
У меня на работе слово microsoft в бане
До чего доводит людей linux
а современные ещё и двубайтовые
Вообще читал описание клавиатур на ixbt, что удивило — игровые обещают слать одновременно чуть ли не два десятка нажатых клавиш, правда не уточняют как.
alexey_public
До чего доводит людей linux
Не, из под линя как раз можно было бы, но фильтр один на всех.
alexey_public
игровые обещают слать одновременно чуть ли не два десятка нажатых клавиш, правда не уточняют как.
Можно предположить, что серией соответствующих сканкодов. Я бы сделал так. Ещё можно и с помощью драйвера, но тогда надо его самому производителю писать под каждую ось.
Tor Bel
Описание устарело. Старые(PC/XT) клавиатуры передавали однобайтовые сканкоды, а современные ещё и двубайтовые.
А внимательно прочитать описание?
Ещё можно и с помощью драйвера
Нельзя. Драйвер берёт готовые скан коды из буфера и обрабатывает их.
alexey_public
Вообще читал описание клавиатур на ixbt, что удивило — игровые обещают слать одновременно чуть ли не два десятка нажатых клавиш, правда не уточняют как.
Я не понимаю людей, которые не читают описание, но начинают обсуждать функционирование прибора. (По принципу — «зная и дурак сможет, а вот попробуй не зная. «?)
Скан кода передаются по нажатию и отпусканию. В игровых клавиатурах имеется в виду не совершенно одновременное нажатие клавиш (это почти невозможно), а передачу информации о одновременно нажатых клавишах, то есть нажать одну, не отпуская, нажать другую, и т.д. А вот это уже зависит от схемотехники контроллера и матрицы сканирования (в принципе, достаточно поставить по диоду на каждую клавишу).
Поскольку контроллер опрашивает клавиши последовательно, то даже физическое одновременное нажатие клавиш всё равно не даст одновременных скан кодов.