На какую клавишу я нажал?

15

Задача состоит в том, чтобы написать код, чтобы определить, какая клавиша нажата на клавиатуре. Вы можете предположить, что одновременно нажимается только одна клавиша и существует стандартная раскладка клавиатуры США. Это макет с @ над 2.

Ваш код должен выводить уникальный идентификатор для любой нажатой клавиши. Это включает PrtScn, Scroll Lock, Pause, Shift влево, Shift вправо, Ctrl влево, Ctrl вправо, Caps Lock, Tab, Enter, Enter на цифровой клавиатуре, Num Lock, Вставка, Ins на цифровой клавиатуре, Backspace, Del, F1 ... F12, Esc, левая клавиша Windows, правая клавиша Windows, Alt, AltGr, клавиша приложения (контекстное меню) и так далее.

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

В своем ответе, пожалуйста, покажите, какой код вы выводите для следующих нажатий клавиш: Tab, Pause, Enter, Enter на цифровой клавиатуре, левая клавиша Windows, правая клавиша Windows, Insert и Ins на цифровой клавиатуре.

Если у вас совсем другая клавиатура, задача по-прежнему состоит в том, чтобы вывести разные идентификаторы для каждой клавиши на клавиатуре.


источник
1
В JS (браузер JS, в любом случае) невозможно проверить, нажаты ли определенные клавиши (например, Caps Lock, Num Lock, Scroll Lock, PrtScn). Означает ли это, что JS не может ответить?
ETHproductions
2
@ETHproductions Это действительно так. Извиняюсь перед любителями JS везде.
2
Требования изменены после предоставления 5 ответов (включая одно, которое сейчас удалено). Это не совсем справедливо ...
Оливье Грегуар
6
Я не думаю, что было бы справедливо / правильно запрашивать вывод для клавиш, которых нет на многих клавиатурах, таких как клавиши Windows и т. Д.
Notts90 отключен для codidact.org
1
@ Notts90 Разве они не являются частью стандартной раскладки клавиатуры США? upload.wikimedia.org/wikipedia/commons/thumb/5/51/...

Ответы:

22

машинный код x86, исполняемый файл DOS, 29 * 28 байт

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Это исполняемый файл COM для MS-DOS , для него требуется совместимое с IBM PC оборудование.
В частности, контроллер 8042 PS / 2 или, скорее, его эмуляция через SMM .
Короче говоря, он должен работать из коробки на любом обычном ПК.

Исходный код

BITS 16

 ;Disable the interrupts so we don't compete with the IRQ 1 (the 8042 main
 ;device IRQ) handler (the ISR n. 9 by default) for the reading of the codes.
 cli

_wait:

 ;Is 'Output buffer full (OBF)' bit set?

 in al, 64h                ;Read the 8042 status register             
 shr al, 1                 ;Move bit 0 (OBF) into the carry flag

jnc _wait                  ;Keep spinning if CF = OBF not set

 ;Read the scan code S
 in al, 60h

 ;Is S a break code?

 shl al, 1                 ;Bit 7 is set if it is
jnc _wait

 ;PART 2

 ;AL = S mod 10h := y, AH = S / 10h := x
 aam 16
 add ax, 2121h             ;Make both quantities in the printable ASCII range (skip space though)

 ;Print y
 xchg dx, ax
 mov ah, 02h
 int 21h                   ;int 21/ah=02 prints the char in DL

 ;DH is still valid here, it holds x. We print it now
 mov dl, dh
 int 21h

 ;Never terminate
jmp _wait

Я разделил программу на две части.

Первая часть посвящена чтению скан-кодов . Скан-коды - это числовые значения, связанные с каждым ключом.
Обратите внимание, что это аппаратный код, он не зависит от ОС или кодировки. Они похожи на закодированную пару (столбец, строку) ключа.
Каждая клавиша имеет скан-код, даже те нестандартные странные функциональные клавиши, которые есть на некоторой клавиатуре (например, клавиша «открыть калькулятор»).
Некоторые ключи имеют многобайтовый скан-код, они имеют префиксы, разработанные для того, чтобы сделать поток декодируемым, просто взглянув на последовательность байтов.
Таким образом, каждый ключ получает свой уникальный идентификатор, даже CTRL, SHIFT, WinKeys и так далее.

Обрабатываются только «коды прерывания», отправленные при отпускании ключа, «коды создания» игнорируются.
У формирователей установлен старший бит (бит 7 для байта), поэтому их легко распознать.

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

Байт xy, где x - верхний полубайт, а y - нижний, выводится как два последовательных символа c 0 и c 1, определенных как:

c 0 = 0x21 + y
c 1 = 0x21 + x

Обратите внимание, что нижний полубайт печатается первым (это избавило меня от обмена).
Обоснование состоит в том, чтобы отобразить каждое из 16 возможных значений клева в последовательные символы ASCII из '!'.
Проще говоря, это шестнадцатеричное число, но с

  1. Клев поменялся
  2. !"#$%&'()*+,-./01 в виде цифры (als) вместо 0123456789abcdef

Запуск его в DOSBox и нажатие некоторой случайной клавиши (некоторые из которых являются специальными клавишами, но обратите внимание, что DOSBox как процесс Windows не может захватить все клавиши) дает

DOSBox запускает идентификатор ключа

Обратите внимание, что эта программа никогда не завершается (кроме того, она берет на себя полный контроль над ПК, отключая прерывания), как я полагаю, было задано вопросом (просто нет уничтожения процессов в DOS).


* Уменьшено благодаря CodyGray .

Маргарет Блум
источник
Получилось ли с помощью INинструкции быть меньше в байтах, чем вызывать прерывания ПЗУ BIOS (например int 16h, функция 10h)?
Коди Грей,
@CodyGray Скорее всего, нет, весь цикл может быть пропущен. Как-то я просто прыгнул прямо к inинструкции. Это на самом деле очень хорошая точка зрения у вас есть. Если вы еще этого не сделали, почему бы не опубликовать его в качестве ответа? :)
Маргарет Блум
1
Ну, теперь ты говоришь сумасшедший! Это звучит как гораздо больше работы, чем просто комментировать ваш существующий ответ. :-p Я играю с тем, чтобы что-то собрать. Тем не менее, забавный совет: когда вы играете в гольф, xchgаккумулятор в качестве одного из регистров составляет 1 байт, так что это лучше, чем 2-байтовый mov.
Коди Грей
1
Хорошо, проблема в int 16hтом, что я не получаю коды сканирования для клавиш Shift, блокировки прокрутки или паузы / прерывания (возможно, других), и это требуется для вызова. Ваше решение чтения входных данных непосредственно из ввода-вывода работает, хотя мне кажется, что оно возвращает одинаковое значение для всех ключей в кластере Ins / Del / Home / End / PgUp / PgDown.
Коди Грей
1
@PeterCordes: также PAUSE ведет себя странно, IIUC отправляет код прерывания вместе с кодом make при нажатии клавиши и ничего не отправляет при отпускании ключа. Или это то, что я понял из энциклопедии компьютерных игр.
ниндзя
12

Java 7 или выше, 246 228 байт

import java.awt.event.*;class K{public static void main(String[]a){new java.awt.Frame(){{addKeyListener(new KeyAdapter(){public void keyPressed(KeyEvent e){System.out.println(e);}});show();setFocusTraversalKeysEnabled(0<0);}};}}

Ungolfed:

import java.awt.event.*;
class K{
    static void main(String[]a){
        new java.awt.Frame(){
            {
                addKeyListener(new KeyAdapter(){
                    public void keyPressed(KeyEvent e){
                        System.out.println(e);
                    }
                });
                show();
                setFocusTraversalKeysEnabled(0<0);
            }
        };
    }
}

-18 благодаря @ OlivierGrégoire для show(), 0<0иimport java.awt.event.*;

Что приводит к:

введите описание изображения здесь

Даже обрабатывает нажатие клавиш Shift для заглавных букв, клавиши Windows, блокировки колпачков и т. Д. Вы можете видеть, что это также печатает «модификаторы», которые являются «удерживаемыми клавишами».

java.awt.event.KeyEvent[KEY_PRESSED,keyCode=27,keyText=Escape,keyChar=Escape,keyLocation=KEY_LOCATION_STANDARD,rawCode=27,primaryLevelUnicode=27,scancode=1,extendedKeyCode=0x1b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=192,keyText=Back Quote,keyChar='`',keyLocation=KEY_LOCATION_STANDARD,rawCode=192,primaryLevelUnicode=96,scancode=41,extendedKeyCode=0xc0] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=9,keyText=Tab,keyChar=Tab,keyLocation=KEY_LOCATION_STANDARD,rawCode=9,primaryLevelUnicode=9,scancode=15,extendedKeyCode=0x9] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=20,keyText=Caps Lock,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=20,primaryLevelUnicode=0,scancode=58,extendedKeyCode=0x14] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=16,keyText=Shift,keyChar=Undefined keyChar,modifiers=Shift,extModifiers=Shift,keyLocation=KEY_LOCATION_LEFT,rawCode=16,primaryLevelUnicode=0,scancode=42,extendedKeyCode=0x10] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyText=Ctrl,keyChar=Undefined keyChar,modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_LEFT,rawCode=17,primaryLevelUnicode=0,scancode=29,extendedKeyCode=0x11] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=524,keyText=Windows,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_LEFT,rawCode=91,primaryLevelUnicode=0,scancode=91,extendedKeyCode=0x20c] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=18,keyText=Alt,keyChar=Undefined keyChar,modifiers=Alt,extModifiers=Alt,keyLocation=KEY_LOCATION_LEFT,rawCode=18,primaryLevelUnicode=0,scancode=56,extendedKeyCode=0x12] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=32,primaryLevelUnicode=32,scancode=57,extendedKeyCode=0x20] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=18,keyText=Alt,keyChar=Undefined keyChar,modifiers=Alt,extModifiers=Alt,keyLocation=KEY_LOCATION_RIGHT,rawCode=18,primaryLevelUnicode=0,scancode=56,extendedKeyCode=0x12] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyText=Ctrl,keyChar=Undefined keyChar,modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_RIGHT,rawCode=17,primaryLevelUnicode=0,scancode=29,extendedKeyCode=0x11] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=37,keyText=Left,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=37,primaryLevelUnicode=0,scancode=75,extendedKeyCode=0x25] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=16,keyText=Shift,keyChar=Undefined keyChar,modifiers=Shift,extModifiers=Shift,keyLocation=KEY_LOCATION_RIGHT,rawCode=16,primaryLevelUnicode=0,scancode=42,extendedKeyCode=0x10] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=38,keyText=Up,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=38,primaryLevelUnicode=0,scancode=72,extendedKeyCode=0x26] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=39,keyText=Right,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=39,primaryLevelUnicode=0,scancode=77,extendedKeyCode=0x27] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=96,keyText=NumPad-0,keyChar='0',keyLocation=KEY_LOCATION_NUMPAD,rawCode=96,primaryLevelUnicode=48,scancode=82,extendedKeyCode=0x60] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=110,keyText=NumPad .,keyChar='.',keyLocation=KEY_LOCATION_NUMPAD,rawCode=110,primaryLevelUnicode=46,scancode=83,extendedKeyCode=0x6e] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=10,keyText=Enter,keyChar=Enter,keyLocation=KEY_LOCATION_NUMPAD,rawCode=13,primaryLevelUnicode=13,scancode=28,extendedKeyCode=0xa] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=107,keyText=NumPad +,keyChar='+',keyLocation=KEY_LOCATION_NUMPAD,rawCode=107,primaryLevelUnicode=43,scancode=78,extendedKeyCode=0x6b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=109,keyText=NumPad -,keyChar='-',keyLocation=KEY_LOCATION_NUMPAD,rawCode=109,primaryLevelUnicode=45,scancode=74,extendedKeyCode=0x6d] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=106,keyText=NumPad *,keyChar='*',keyLocation=KEY_LOCATION_NUMPAD,rawCode=106,primaryLevelUnicode=42,scancode=55,extendedKeyCode=0x6a] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=34,keyText=Page Down,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=34,primaryLevelUnicode=0,scancode=81,extendedKeyCode=0x22] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=33,keyText=Page Up,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=33,primaryLevelUnicode=0,scancode=73,extendedKeyCode=0x21] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=35,keyText=End,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=35,primaryLevelUnicode=0,scancode=79,extendedKeyCode=0x23] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=36,keyText=Home,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=36,primaryLevelUnicode=0,scancode=71,extendedKeyCode=0x24] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=46,primaryLevelUnicode=0,scancode=83,extendedKeyCode=0x7f] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=155,keyText=Insert,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=45,primaryLevelUnicode=0,scancode=82,extendedKeyCode=0x9b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=123,keyText=F12,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=123,primaryLevelUnicode=0,scancode=88,extendedKeyCode=0x7b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=122,keyText=F11,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=122,primaryLevelUnicode=0,scancode=87,extendedKeyCode=0x7a] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=121,keyText=F10,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=121,primaryLevelUnicode=0,scancode=68,extendedKeyCode=0x79] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=120,keyText=F9,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=120,primaryLevelUnicode=0,scancode=67,extendedKeyCode=0x78] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=119,keyText=F8,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=0,scancode=66,extendedKeyCode=0x77] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=118,keyText=F7,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=118,primaryLevelUnicode=0,scancode=65,extendedKeyCode=0x76] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=117,keyText=F6,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=117,primaryLevelUnicode=0,scancode=64,extendedKeyCode=0x75] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=116,keyText=F5,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=116,primaryLevelUnicode=0,scancode=63,extendedKeyCode=0x74] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=115,keyText=F4,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=115,primaryLevelUnicode=0,scancode=62,extendedKeyCode=0x73] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=114,keyText=F3,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=114,primaryLevelUnicode=0,scancode=61,extendedKeyCode=0x72] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=113,keyText=F2,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=113,primaryLevelUnicode=0,scancode=60,extendedKeyCode=0x71] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=112,keyText=F1,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=112,primaryLevelUnicode=0,scancode=59,extendedKeyCode=0x70] on frame0
Урна волшебного осьминога
источник
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Деннис
11

HTML (с Javascript), 46 31 символ, 46 31 байт

Используя это для различения ввода и возврата с помощью numpad, LControl и RControl ... Уже нет, поскольку апсиллеры нашли способ сделать это с помощью вызова функции signle.

<body onkeyup=alert(event.code)

Конкретные результаты:

РЕЗУЛЬТАТЫ, КОТОРЫЕ ВСЕ ЕЩЕ С ЦИФРАМИ, Я НЕ МОГУ ТЕСТИРОВАТЬ НА МОЕЙ НОУТБУКЕ,
ПОЖАЛУЙСТА, ПОДОЖДИТЕ, ЧТОБЫ Я ДОСТУП К ЭТИМ КЛЮЧАМ

PrtScn -> PrintScreen
Scroll Lock -> ScrollLock
Pause -> Pause
влево Shift -> ShiftLeft
вправо Shift -> ShiftRight
влево Ctrl -> ContrlLeft
вправо Ctrl -> ControlRight
Caps Lock ->
вкладка CapsLock -> вкладка CapsLock -> вкладка
Enter -> Enter
введите число pad -> NumpadEnter
Num Lock -> NumLock
Вставить -> Вставить
модули на цифровой клавиатуре ->
Backspace Numpad0 -> Backspace
Del -> Удалить
F1 ... F12 -> От F1 до F12
Esc
-> Выход из левой клавиши Windows -> MetaLeft
right Клавиша Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (глючит, обнаруживает ControlLeft, а затем AltRight,но это действительно AltRight)
ключ приложения (контекстное меню) -> ContextMenu

РЕДАКТИРОВАТЬ:
1 байт сохранен ;после вызова функции.
18 байтов, сохраненных благодаря Lil 'Bits и ETHproductions, они заметили, что я забыл сократить имена функций и переменных.
32 байта сэкономлено благодаря RogerSpielker, он заметил, что я делал sparated код без причины; и снова -2 байта: onkeydown-> onkeyup
1 байт сохранен: не требуется финальная косая черта
2 байта сохранены благодаря CraigAyre: with()функция
сохранена 2 байта благодаря только ASCII: keyвместо which
4 байтов сохранено, так как у нас есть текст, в этом нет необходимости for '-'+(каждый идентификатор уникален без этого) 1 байт сохранен благодаря ASCII-only (опять же): больше нет закрывающего символа, > 15 байт сохранено благодаря апсиллерам, как сказано в верхней части моего ответа.

<body onkeyup=alert(event.code)

В. Куртуа
источник
Подождите ... как ... Caps Lock ... обнаружен? Я думал, что это невозможно ... Да ладно. PrtScn и SysRq у меня не работают, но я на ноутбуке с маленькой клавиатурой, которая использует Fn + End и Fn + Home для этих двух клавиш.
ETHproductions
Мне нравится этот ответ, но, похоже, есть некоторые проблемы. Tab ничего не сообщает мне, когда я тестирую это по адресу codepen.io/anon/pen/MoLPQM . Также F12, PrtScn не следует этому правилу: «Он не должен выполнять никаких других действий от нажатий клавиш, которые он получает, и не должен выводить ничего, кроме уникального идентификатора».
@Lembik с использованием html, на самом деле невозможно запретить системе использовать ключ. Вы должны заставить его не распознавать ключевые вводы с помощью машинного (или системного) эффективного языка (например, C). И что касается табуляции, я не знаю, в каких условиях это работает (я имею в виду, иногда это работает, а иногда нет, я не знаю, как мой ответ относится к проходимым ключам.
В. Куртуа
@Lembik Если вы просматриваете код в автономном режиме (не во фрагменте, не на скрипке и т. П.), На полноэкранной странице (например, с помощью F11), то она захватывает вкладки; тот факт, что он не захватывает вкладки, является функцией состояния большей среды браузера, а не кода, запускаемого на странице. Что касается предотвращения поведения по умолчанию, <body onkeydown=return!!alert(event.code)>должен сделать трюк, вернув falseнаkeydown
apsillers
8

Tcl / Tk, 22 символа

bind . <Key> {puts %K}

Образец прогона:

ключи, определенные Tcl / Tk

Примечания:

  • Нет правильной клавиши Windows на моей клавиатуре ☹ ( умный дизайнер поставил переключатель подсветки на место)
  • Вставка числовой панели генерирует другой код в зависимости от статуса NumLock
  • Регулятор громкости генерирует специальные коды X.org, все остальные являются просто обычными клавишами
manatwork
источник
6

Bash с X.org, 21 байт

xev|awk 'NR%2&&/\(k/'

К сожалению, я не могу проверить это, так как я на MacBook под Linux - нет PrntScr, нет цифровой клавиатуры и все такое.

xevэто инструмент, который выводит события мыши и клавиатуры под X.org. Я передаю его в awk, фильтрую четные строки (поскольку каждая клавиша отображается при нажатии клавиши, а затем, когда она отпущена), и выбираю только те, которые содержат (k- эта строка находится в каждой строке, которая описывает нажатую клавишу.

enedil
источник
Не могли бы вы добавить пример выходных данных, перечисленных в вопросе, пожалуйста.
1
@Lembik все выходные данные появляются после выхода.
enedil
Ах. Это не то, что требует спецификация. Я проясню это сейчас.
Это дает синтаксическую ошибку сейчас.
3
Обратите внимание, что Linux не подразумевает X11. например, это не будет работать на текстовой консоли (используйте showkey -sтам: P) или на чистом рабочем столе Wayland GUI. Это действительно ответ bash + Xorg.
Питер Кордес
5

C и Win32, 240 224 216 205 202 194 191 байт

#include<d3d.h>
#include<stdio.h>
w[9];p(x,y,a,b){printf("%X",a^b);}main(){w[1]=p;w[9]=p;CreateWindow(RegisterClass(w),0,1<<28,0,0,0,0,0,0,0,0);for(;GetMessage(w,0,16,0);)DispatchMessage(w);}

Выходы

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

объяснение

#include <d3d.h> // shortest built-in header that includes windows.h
#include <stdio.h> // for printf

w[9]; // space for wndclass-data array

// function castable to the signature of WNDPROC
p(x,y,a,b)
{
    // key and state are encoded in the last two 4-byte arguments to wndproc
    printf("%X",a^b);
}

main(m)
{
    // set minimal window class equivalent data pointing to wndproc above
    w[1]=p;w[9]=p;

    // create the window using the class, with WS_VISIBLE flag
    CreateWindow(RegisterClass(w),0,1<<28,0,0,0,0,0,0,0,0)
    for(;GetMessage(w,0,16,0);) // filter messages 15 and lower, which fire without input
        DispatchMessage(w);
}

Правки

-16 благодаря @ugoren

-8: изменено WNDCLASSна intмассив, так как все 10 членов имеют 4 байта

-11: частичная инициализация массива wndclass-data, уменьшена до 9 элементов

-3: использовать неявный intdecl для массива wndclass-data

-8: удалить символ новой строки из выходного формата (не требуется в спецификациях и сбрасывает printf сразу без него); перейти RegisterClassв CreateWindowarg, используя return ATOM; установите имя wndclass, mкоторому нужен только нулевой байт, чтобы быть допустимой строкой.

-3: повторно использовать wvar для MSGданных

MooseBoys
источник
Делать то же самое с C ++ с помощью cout не намного короче?
onurcanbektas
@ Лет нет. <iostream>+ Длиннее std::cout<<a^b<<"\n". Кроме того, я думаю, что вам нужно добавить возвращаемые типы в функцию decls, и они mне могут быть неявными int.
MooseBoys
Сохранить символ сfor(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
Угорен
Также p(x,y,a,b)и (void*)pстоит сэкономить.
Угорен
3

Java (OpenJDK 8) , 369 байт

import java.awt.event.*;import javax.swing.*;class F{public static void main(String[] a){JFrame f=new JFrame();f.addKeyListener(new KeyListener(){public void keyPressed(KeyEvent e){System.out.print(e.getKeyCode()*8+e.getKeyLocation());}public void keyTyped(KeyEvent e){}public void keyReleased(KeyEvent e){}});f.setVisible(true);f.setFocusTraversalKeysEnabled(false);}}

Это не может быть выполнено с TIO, потому что он использует графический интерфейс, но он работает на моем компьютере.

Пауза: 153
Enter: 81
Вход на NumPad: 84
Слева супер ключ: 193 (после отключения ярлыка Меню на моем рабочем столе)
Правый супер ключ: 201
Вставка: 241
Вставьте на Numpad: 522948 (у меня его нет, но это то, что вы получаете, когда нажимаете 5 с отключенной Num Lock. Когда включена Num Lock, вы получаете 812.)

Ungolfed / Объяснение:

import java.awt.event.*; // KeyListener, KeyEvent
import javax.swing.*; // JFrame

class F implements KeyListener {

    public static void main(String[] a) {
        JFrame f=new JFrame(); // creates a new GUI frame
        f.addKeyListener(new KeyListener() {  // puts a KeyListener in the frame with the following properties:

            // Method that runs whenever a key is pressed
            public void keyPressed(KeyEvent e) {
                // getKeyCode returns an integer that uniquely identifies the key,
                // but not the location (e.g. LShift and RShift have the same key code)
                // To fix this, I scale up the key code by 8 and add the location,
                // which is always 0-4 (Standard, Left, Right, NumPad, or Unknown)
                // I could have scaled by 5 instead but I wasn't really thinking
                System.out.print(e.getKeyCode() * 8 + e.getKeyLocation());
                // If you want nicer-looking output, just change "print" to "println"
            }

            // Method that runs whenever a printable character is typed (does nothing)
            public void keyTyped(KeyEvent e){}

            // Method that runs whenever a keyboard key is released (does nothing)
            public void keyReleased(KeyEvent e){}
        });

        f.setVisible(true); // the frame will only except key presses if it is visible
        f.setFocusTraversalKeysEnabled(false); // disables "focus traversal" keys (such as Tab) from actually traversing focus
    }
}
musicman523
источник
Не похоже, что это работает для клавиши табуляции?
Poke
setFocusTraversalKeysEnabled(false);в вашем ответе это исправят.
Волшебная Урна Осьминога
@MagicOctopusUrn Я не знаю, что это делает, и я не думаю, что хочу: P
musicman523
Он заставляет ваш ответ работать для клавиши TAB, так как без него ваш ответ недействителен.
Волшебная Урна Осьминога
Оооооо я вижу - Tab - это «ключ обхода фокуса»
musicman523
3

Scala 2.10+, 279 символов, 279 байтов

Теперь это ответ scala :), хотя я чувствую, что я делаю Java. Во всяком случае, мы не можем проверить это на TIO.

import scala.swing._
import java.awt.event._
object M extends SimpleSwingApplication{def top=new MainFrame{this.peer.addKeyListener(new KeyListener(){def keyPressed(e:KeyEvent){print(e.getKeyCode+"-"+e.getKeyLocation)}
def keyReleased(e:KeyEvent){}
def keyTyped(e:KeyEvent){}})}}

Печально, что нам нужно объявлять все унаследованные методы, даже если мы их не используем: я могу удалить их из числа байтов, так как некоторые флаги компилятора могут разрешить не объявлять их?

Это печатает (как для моего ответа html-js) нажатую клавишу «-», а затем его «местоположение».

Например :

PrtScn -> не проверяемый
Scroll Lock -> 145-1
Пауза -> 19-1
Shift влево -> 16-2
Shift вправо -> 16-3
влево Ctrl -> 17-2
вправо Ctrl -> 17-3
Caps Lock ->
Вкладка 20-1 -> невозможно проверить
Ввод -> 10-1
Ввести на цифровой клавиатуре -> 10-4
Num Lock -> 144-4
Вставить -> 96-1 Ввод
на цифровой клавиатуре -> 96-4
Backspace -> 8-1
Del -> 127-1
F1 ... F12 -> 112-1 до 123-1
Esc -> 27-1
левая клавиша Windows -> 524-2
правая клавиша Windows -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (вид глючит, обнаруживает 17-2, а затем 18-3,но это действительно 18-3)
ключ приложения (контекстное меню) -> 525-1

Хотя я думаю, что это зависит от компьютера: / Я сейчас на ноутбуке с азертами.

В. Куртуа
источник
Если вы не хотите считать ненужные объявления, вам, возможно, придется включить длину нестандартных флагов компилятора. Разве старые компиляторы использовали по умолчанию для этого? Ответы на C обычно нужно компилировать, -std=c89поскольку современные компиляторы по умолчанию используют c99 или c11, но не нужно это считать. Так что я не уверен, что решение будет из мета-кода гольф.
Питер Кордес
3

TI-BASIC, 19 байтов

ПРОГРАММА: S

If Ans
Disp Ans
getKey
prgmS
  • Введите: 105,
  • Левый ключ: 24,
  • Правый ключ: 26,
  • Ins [ert] немного отличается, потому что обычно требуется два нажатия для перехода, но это будет 21, а затем 23.

Вот иллюстрация остальных клавиш:

введите описание изображения здесь

Объяснение:

ПРОГРАММА: S Редактор отображает имя вверху отдельно от кода; имя "S"

If Ans    // If the last input isn't zero
Disp Ans  // Display the last input
getKey    // Input a key press
prgmS     // Call the same program in a recursive fashion

К сожалению, это невозможно сделать в Arnold C, поэтому мне пришлось придерживаться TI-BASIC.

bearacuda13
источник
1
Это работает для каждого ключа в этой картине? Если нет, для каких ключей он не работает?
2
Да, это работает для каждой клавиши, кроме кнопки включения, зарезервированной для уничтожения программы без вытягивания батареи из калькулятора.
bearacuda13
@ bearacuda13: у меня есть такой же калькулятор, который я купил 18 лет назад и не знал ключевой детали ON в течение многих лет. Я использовал его с конца университета (11 лет назад), но кто знает ...
sergiol
1

C #, 144 + 601 = 745 байт

Состоит из двух классов, мне не удалось успешно объединить их в один класс.

Основной класс:

namespace System.Windows.Forms{class P:Form{static void Main(){Application.Run(new P());}P(){new Reflection.M().U+=k=>Console.Write(k.f+k.v);}}}

Крюк класс:

namespace System.Reflection{using Runtime.InteropServices;public class M{public delegate void d(s s);event d u;public event d U{add{if(h<1){j=m;h=SetWindowsHookEx(13,j,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);}u+=value;}remove{u-=value;}}public struct s{public int v;public int c;public int f;}[DllImport("user32.dll")]static extern int SetWindowsHookEx(int idHook,p lpfn,IntPtr hMod,int dwThreadId);delegate int p(int c,int w,IntPtr l);p j;int h;int m(int c,int w,IntPtr l){if(c>=0&u!=null&(w==257|w==261))u.Invoke((s)Marshal.PtrToStructure(l,typeof(s)));return -1;}}}

Выходы:

  • Tab: 137
  • Пауза: 147
  • Войти: 141
  • NumPad Введите: 142
  • Левые окна: 220
  • Правильные окна: 221
  • Вставка: 174
  • Вставка NumPad: 224
TheLethalCoder
источник
Я могу немного уменьшить количество байтов, переходя ||на |другие подобные игры, но мой мозг нуждается в отдыхе после этого!
TheLethalCoder
В классе Хук, я думаю, public int v;public int c;public int f;можно сократить доpublic int v,c,f;
Вопросительные знаки
@QuestionMarks Хорошей идеей станет игра в гольф, когда я вернусь к компьютеру
TheLethalCoder
1

AutoHotkey , 26 байт

loop{
input,x,L1M
send %x%
}

Не могу проверить (только для побед), но Mопция говорит

M: Измененные нажатия клавиш, такие как Control-A - Control-Z, распознаются и транскрибируются, если они соответствуют реальным символам ASCII.

Так что должно быть хорошо.

phil294
источник
1

WinApi C ( gcc ), 156 байт

#include <d3d.h>
#define b GetStdHandle(-10)
BYTE i[20];main(){SetConsoleMode(b,0);a:ReadConsoleInput(b,i,1,i+5);*i^1||*(i+4)||printf("%X\n",i[10]);goto a;}

Эта программа печатает код виртуальной клавиши Windows, связанный с каждой клавишей ввода. \nВ printfформате струне не является обязательным (но делает выход человека дружественным) и может быть отброшены на общий балл 154 байт . Простой способ убить программу (без taskmgr) - с помощью CTRL + PAUSE. Если у вас есть клавиатура с клавишей Fn, эта программа не сможет ее поднять, так как она даже не замечена Windows.

  • Благодарю ответ MooseBoys за #include <d3d.h>трюк и вдохновение для BYTEмассива.

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

#include <windows.h>
#include <stdio.h>

int main(void)
{
    HANDLE conIn = GetStdHandle(STD_INPUT_HANDLE);
    INPUT_RECORD ir;
    DWORD useless;

    SetConsoleMode(conIn, 0);

    for(;;)
    {
        ReadConsoleInput(conIn, &ir, 1, &useless);

        if(ir.EventType == KEY_EVENT && !ir.Event.KeyEvent.bKeyDown)
            printf("%X\n", ir.Event.KeyEvent.wVirtualKeyCode);
    }

    return 0;
}
Сэр рандом
источник
1

C (gcc) + Win32, 94 95 98 105 107 110 байтов

#import"d3d.h"
j;f(){for(;;)for(j=191;j--;)GetAsyncKeyState(j)&(j<16||j>18)?printf("%d",j):0;}

Код захватывает ключи даже после потери фокуса.

Следующие снимки экрана записаны с добавлением пробелов между выходами ( printf("%d ",j);+1 байт) для лучшей читаемости:

ключевой скриншот

Left-ctrl Left-win Left-alt Space Right-alt Right-win Right-menu Right-ctrl Left-shift Z X C Right-shift Left-shift 1 2 3 Num 1 Num 2 Num 3 Left-shift +/= (on the main part) Num + Left-alt PrtScn

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

(j<16||j>18)Фильтры обычные Ctrl / Alt / Shift. 16/17/18 запускается всякий раз, когда нажимается левый или правый, вместе со значением vkey, указанным в местоположении.

Кейу Ган
источник
1

PowerShell, 34 байта

$Host.UI.RawUI.ReadKey().Character

Выходы в той же строке, что и вход, что может немного запутать.

Габриэль Миллс
источник