Когда вы нажимаете клавишу на клавиатуре, компьютер получает не просто букву или символ, а числовой код, который идентифицирует именно эту кнопку. Но мало кто знает, что у одной клавиши может быть три разных «номера» — и каждый используется в своём контексте. Почему так происходит? Дело в том, что путь сигнала от физической кнопки до отображения символа на экране проходит через несколько слоёв обработки: от аппаратного скан-кода до программного ASCII-значения.
Для обычного пользователя эти нюансы не критичны, но они становятся ключевыми, если вы:
- Пишете макросы или скрипты для автоматизации (например, в AutoHotkey или Python).
- Разрабатываете игры или приложения, где нужно отслеживать нажатия клавиш.
- Настраиваете нестандартные раскладки или перехватываете клавиатурный ввод на низком уровне.
В этой статье мы разберём все три типа «номеров» клавиш — от аппаратных до программных — и покажем, как их узнать на практике.
1. Скан-код (Scan Code) — аппаратный идентификатор клавиши
Скан-код — это уникальный номер, который присваивается каждой физической клавише на клавиатуре на уровне контроллера устройства. Он не зависит от операционной системы, раскладки или языка — это «железный» идентификатор, который передаётся в компьютер при нажатии.
Например, клавиша A на английской и русской раскладке будет иметь один и тот же скан-код, потому что речь идёт о физической кнопке, а не о символе. Скан-коды стандартизированы для большинства клавиатур (особенно в рамках протокола USB HID), но могут немного отличаться для редких или кастомных устройств.
Где используется скан-код?
- 🔌 В драйверах клавиатур для определения, какая именно кнопка была нажата.
- 🎮 В игровых контроллерах и устройствах ввода (например, для эмуляции клавиатуры на джойстиках).
- 🖥️ В BIOS/UEFI для обработки нажатий до загрузки ОС.
Скан-коды бывают двух типов:
- Set 1 — устаревший стандарт (использовался в XT/AT-клавиатурах).
- Set 2/3 — современные стандарты для USB и PS/2.
Например, клавиша Enter в Set 2 имеет скан-код 0x1C, а в Set 1 — 0x5A.
2. Виртуальный код (Virtual Key Code, VK) — программный идентификатор в ОС
Когда скан-код попадает в операционную систему, он преобразуется в виртуальный код (VK) — числовое значение, которое уже понимает Windows, Linux или macOS. В отличие от скан-кода, VK зависит от ОС и может меняться в разных версиях.
Например, в Windows виртуальный код клавиши A — это 0x41 (65 в десятичной системе), независимо от раскладки. А клавиша Enter всегда будет иметь VK 0x0D (13). Эти коды используются в API функциях вроде GetAsyncKeyState или keybd_event.
Вот несколько примеров VK-кодов в Windows:
| Клавиша | VK (шестн.) | VK (десят.) | Константа в WinAPI |
|---|---|---|---|
Esc | 0x1B | 27 | VK_ESCAPE |
Space | 0x20 | 32 | VK_SPACE |
Left Shift | 0xA0 | 160 | VK_LSHIFT |
F1 | 0x70 | 112 | VK_F1 |
Backspace | 0x08 | 8 | VK_BACK |
В Linux аналогичную роль играют keycodes, которые можно посмотреть через команду xev или в файле /usr/include/linux/input-event-codes.h. Например, клавиша Q в Linux обычно имеет keycode 16.
⚠️ Внимание: Виртуальные коды в macOS (CGKeyCode) отличаются от Windows и Linux. Например, клавишаCommandв macOS имеет код55, тогда какWinв Windows —0x5B(91).
3. ASCII и Unicode — символьное представление клавиши
Если скан-код и VK идентифицируют физическую клавишу, то ASCII/Unicode — это уже символ, который появляется на экране. Например, при нажатии A в английской раскладке генерируется ASCII-код 65 (буква «A»), а в русской — 1040 (буква «Ф» в Unicode).
Важно понимать разницу:
- 🔤 ASCII — устаревший стандарт (0–127), покрывающий латиницу, цифры и спецсимволы.
- 🌍 Unicode — современный стандарт (включает кириллицу, иероглифы, эмодзи и т. д.).
Например, символ «@» в ASCII имеет код 64, а в Unicode — U+0040.
Как это работает на практике?
- 📝 В текстовых редакторах (например, Notepad++) можно вставлять символы по их коду через
Alt + [число]. - 🎮 В играх иногда требуется вводить спецсимволы (например, для ников или чата).
- 🔧 При программировании строковые функции (
charCodeAt()в JavaScript) работают с Unicode.
4. Как узнать скан-код, VK и ASCII клавиши на практике
Рассмотрим инструменты для определения всех трёх «номеров» клавиши в разных ОС.
🪟 Windows
Для просмотра VK и скан-кодов:
- Стандартный способ: Используйте утилиту KeyEvent Tester (входит в состав Windows SDK) или AutoHotkey со скриптом:
#InstallKeybdHook~*::ToolTip, Scan: % "0x" . Format("{:02X}", A_ScanCode) `nVK: % "0x" . Format("{:02X}", A_VK) `nChar: % A_ASCII
- Для разработчиков: Функция
MapVirtualKeyв WinAPI преобразует VK в скан-код и обратно.
🐧 Linux
В Linux проще всего использовать:
xev— показывает keycode, keysym (символ) и состояние модификаторов.showkey— выводит скан-коды в консоли (работает без X-сервера).evtest— утилита для мониторинга событий ввода (включая клавиатуру).
Пример вывода xev для клавиши A:
KeyPress event, serial 36, synthetic NO, window 0x4a00001,
root 0x1a5, subw 0x0, time 12345678, (100,200), root:(300,400),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES
Здесь keycode 38 — это Linux-keycode, а keysym 0x61 — Unicode-символ «a».
🍎 macOS
В macOS для просмотра кодов клавиш:
- Используйте Key Codes (утилита из Apple Developer Tools).
- Или запустите в Terminal:
sudo opensnoop | grep "keyboard"
Установите AutoHotkey|Создайте скрипт с ToolTip|Нажмите интересующую клавишу|Запишите значения Scan/VK/ASCII|Проверьте в документации WinAPI при необходимости-->
5. Примеры использования кодов клавиш
Знание скан-кодов, VK и ASCII пригождается в неожиданных ситуациях. Рассмотрим несколько практических кейсов.
🤖 Автоматизация и макросы
В AutoHotkey можно привязывать действия к конкретным VK или скан-кодам. Например, скрипт для блокировки клавиши Caps Lock (VK = 0x14):
CapsLock::return ; просто игнорирует нажатие
Или эмуляция нажатия Win + R по скан-коду:
#IfWinActive, ahk_exe notepad.exe
$F1::Send #{r} ; VK для F1 = 0x70, но здесь используется символьное имя
🎮 Разработка игр
В игровых движках (например, Unity или Unreal Engine) часто требуется обрабатывать нажатия на низком уровне. Например, в Unity (C#) проверка нажатия клавиши W может выглядеть так:
if (Input.GetKey(KeyCode.W)) {
// Движение вперёд
}
Здесь KeyCode.W — это обёртка над VK-кодом.
🔧 Диагностика клавиатуры
Если клавиша не работает, скан-код помогает понять, проблема в аппаратной части (не приходит скан-код) или в ПО (скан-код есть, но VK не генерируется). Например, если при нажатии Space в xev не появляется событие KeyPress, дело в клавиатуре или подключении.
⚠️ Внимание: Некоторые клавиатуры (особенно игровые с программируемыми клавишами) могут отправлять нестандартные скан-коды. В этом случае для корректной работы может потребоваться специальный драйвер от производителя.
6. Частые ошибки и нюансы
Работа с кодами клавиш кажется простой, но здесь есть подводные камни, о которых многие не знают.
Ошибка 1: Путаница между скан-кодом и VK
Часто пользователи пытаются использовать скан-код там, где нужен VK, и наоборот. Например, в AutoHotkey функция Send работает с VK, а не со скан-кодами. Если вы укажете скан-код вместо VK, клавиша либо не сработает, либо вызовет другое действие.
Ошибка 2: Игнорирование модификаторов
Клавиши-модификаторы (Shift, Ctrl, Alt) влияют на конечный символ, но не всегда на VK. Например, VK для Shift + A остаётся 0x41, но ASCII-символ меняется на 65 (заглавная «A»). В некоторых API (например, WM_KEYDOWN в Windows) модификаторы передаются отдельно.
Ошибка 3: Разные раскладки = разные символы
Если вы пишете макрос для ввода текста, учитывайте, что VK клавиши A одинаковый в любой раскладке, но результирующий символ будет разным. Например, в русской раскладке VK 0x41 даст букву «Ф», а не «A». Чтобы избежать проблем, используйте:
- 📌
SendInputс явным указанием Unicode-символа. - 📌 Проверку текущей раскладки через
GetKeyboardLayout(Windows).
Почему клавиша Print Screen ведёт себя странно?
Клавиша Print Screen имеет VK 0x2C, но в большинстве систем её нажатие не генерирует событие WM_KEYDOWN в обычных окнах. Вместо этого ОС перехватывает её на уровне ядра для создания скриншота. Чтобы отследить её программно, нужно использовать низкоуровневые хуки (WH_KEYBOARD_LL в Windows) или проверять буфер обмена на изменения.
7. Таблица соответствия для популярных клавиш
Ниже приведена сводная таблица скан-кодов (Set 2), VK (Windows) и ASCII/Unicode для часто используемых клавиш. Обратите внимание, что значения могут незначительно отличаться для нестандартных клавиатур.
| Клавиша | Скан-код (Set 2, шестн.) | VK (Windows, шестн.) | ASCII/Unicode (десят.) | Примечания |
|---|---|---|---|---|
Enter |
0x1C |
0x0D |
13 (\r) |
В Linux keycode обычно 36. |
Esc |
0x01 |
0x1B |
27 | Используется для выхода из полноэкранных режимов. |
Tab |
0x0F |
0x09 |
9 (\t) |
В браузерах переключает фокус между элементами. |
Backspace |
0x0E |
0x08 |
8 (\b) |
Удаляет символ слева от курсора. |
Space |
0x39 |
0x20 |
32 | Самая широкая клавиша на клавиатуре. |
Важно: Скан-коды для клавиш-модификаторов (Shift, Ctrl, Alt) могут отличаться для левой и правой сторон клавиатуры. Например, Left Shift имеет VK 0xA0, а Right Shift — 0xA1.
8. Полезные инструменты для работы с кодами клавиш
Если вам регулярно приходится работать с кодами клавиш, эти инструменты сэкономят время:
- 🛠️ AutoHotkey — скриптовый язык для автоматизации действий на клавиатуре. Позволяет перехватывать и эмулировать нажатия по VK или скан-кодам.
- 📊 KeyEvent Tester (входит в Windows SDK) — показывает все три типа кодов в реальном времени.
- 🐧 evtest (Linux) — мониторит события ввода, включая клавиатуру, мышь и тачпад.
- 🍎 Key Codes (macOS) — утилита для просмотра CGKeyCode и Unicode.
- 🌐 Online Key Code Checker — веб-сервисы вроде keycode.info (показывают JavaScript-события клавиш).
Для разработчиков:
- 📚 Документация WinAPI — описание функций
GetAsyncKeyState,MapVirtualKeyи др. - 📖 Linux input-event-codes.h — список keycodes для Linux.
- 🎓 Unicode Consortium — полная таблица символов и их кодов.
FAQ: Частые вопросы о кодах клавиш
Можно ли изменить скан-код клавиши?
Нет, скан-код жёстко прописан в контроллере клавиатуры. Однако можно переназначить его обработку на уровне ОС (например, через реестр Windows или xmodmap в Linux) или с помощью специализированного ПО вроде SharpKeys.
Почему одна клавиша может отправлять разные VK в разных ОС?
Потому что виртуальные коды зависят от реализации API операционной системы. Например, VK для Win-клавиши есть только в Windows, а в Linux или macOS её аналог (Super или Command) будет иметь другой код.
Как эмулировать нажатие клавиши по её коду в Python?
Используйте библиотеку pyautogui для высокоуровневой эмуляции или ctypes для вызова WinAPI. Пример:
import ctypes
ctypes.windll.user32.keybd_event(0x41, 0, 0, 0) # Нажатие 'A' (VK=0x41)
ctypes.windll.user32.keybd_event(0x41, 0, 0x0002, 0) # Отпускание 'A'
Что такое «мёртвые клавиши» и как их обрабатывать?
«Мёртвые клавиши» (например, ^ на французской раскладке) не генерируют символ сразу, а модифицируют следующее нажатие. В кодах клавиш они обычно имеют стандартный VK, но их обработка требует проверки состояния клавиатуры через ToUnicode (Windows) или XmbLookupString (Linux).
Почему некоторые клавиши (например, Fn) не имеют VK?
Клавиша Fn обрабатывается на уровне BIOS или драйвера клавиатуры и не передаётся в ОС как отдельное событие. Её функциональность реализуется через комбинации с другими клавишами (например, Fn + F1).