Яку клавішу я натиснув?


15

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

Ваш код повинен вивести унікальний ідентифікатор для будь-якої натиснутої клавіші. Сюди входить PrtScn, Блок прокрутки, Пауза, Зміна вліво, Права Зміна, Ліва Ctrl, Права Ctrl, Caps Lock, Tab, Enter, Enter на цифровій панелі, Num Lock, Insert, Ins на цифровій панелі, Backspace, Del, F1 ... F12, Esc, ліва клавіша Windows, права клавіша Windows, Alt, AltGr, ключ програми (контекстне меню) тощо.

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

У своїй відповіді, будь ласка, покажіть, що ви кодуєте для наступних натискань клавіш: вкладка, призупинення, введення, введення на цифровій панелі, ліва клавіша Windows, права клавіша Windows, вставка та ін на цифровій панелі.

Якщо у вас зовсім інша клавіатура, завдання все одно виводить різний ідентифікатор для кожної клавіші на вашій клавіатурі.


1
У JS (браузер JS у будь-якому випадку) неможливо перевірити, чи натиснуті певні клавіші (наприклад, Caps Lock, Num Lock, 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

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

Перша частина стосується зчитування скан-кодів . Scancodes - це числові значення, пов'язані з кожною клавішею.
Зауважте, що це апаратний код, вони не залежать від ОС або набору даних. Вони схожі на закодовану пару (стовпець, рядок) ключа.
Кожна клавіша має код сканування, навіть ті нестандартні дивні функціональні клавіші, які знаходяться на якійсь клавіатурі (наприклад, клавіша "відкритий виклик").
Деякий ключ має багатобайтовий код сканування, вони мають префікси, призначені для того, щоб зробити потік декодируемым, просто переглянувши послідовність байтів.
Таким чином, кожен ключ отримує свій унікальний ідентифікатор, навіть CTRL, SHIFT, WinKeys тощо.

Обробляються лише "коди розриву", що надсилаються при відпуску ключа, ігноруються "make code".
Формувальники мають вищий біт (біт 7 за байт), тому їх легко розпізнати.

Друга частина стосується друку байта.
Друк завжди тривалий у складанні, у нас немає вбудованих.
Щоб вона була короткою, а оскільки потрібно було написати ідентифікатор ключа, я відмовився від десяткових чи шістнадцяткових цифр на користь особистого кодування.

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

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

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

  1. Гриз обмінявся
  2. !"#$%&'()*+,-./01 як цифра (аль) замість 0123456789abcdef

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

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

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


* Знижена подяка CodyGray .


Чи вдалося за допомогою INінструкції бути меншим за байтами, ніж виклик переривань BIOS 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 надсилає код перерви разом з внесенням коду під час натискання клавіші, а при відпуску ключа нічого не надсилає. Або це я зрозумів із Енциклопедії програмування ігор на ПК.
ніндзя

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);}};}}

Безголівки:

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.*;

Результати:

enter image description here

Навіть обробляє натискання змін для великих літер, клавіші 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 ... Не більше, оскільки апсилери знайшли спосіб зробити це за допомогою виклику функції знака.

<body onkeyup=alert(event.code)

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

ВИСТАВКИ, ЩО ПІДТРИМУЮТЬСЯ З ЧИСЕЛЬНЯМИ - ТИХ, Я НЕ МОЖУ ТЕСТУВАТИ НА МОЄМУ ЛАПТОПІ
БУДЬ ЛАСКА, ЧАЙТЕ МНЕ ДОПОМОГАТИ ДО ЦІХ КЛЮЧІВ

PrtScn ->
Блокування прокрутки PrintScreen ->
Пауза прокруткиLock -> Призупинення
ліворуч Shift -> ShiftLeft
вправо Shift -> ShiftRight
ліворуч Ctrl -> ContrlLeft
вправо Ctrl -> ControlRight
Caps Lock ->
Вкладка CapsLock -> Вкладка
Введення -> Введіть
введіть номер pad -> NumpadEnter
Num Lock -> NumLock
Insert -> Вставити
Ins на цифрову панель -> Numpad0
Backspace -> Backspace
Del -> Delete
F1 ... F12 -> F1 to F12
Esc -> Escape
зліва клавіша Windows -> MetaLeft
праворуч Ключ Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (вид баггі, він виявляє ControlLeft, а потім AltRight,але це справді AltRight)
програми (контекстне меню) -> ContextMenu

EDITs:
1 байт збережено ;після виклику функцій
18 байт збережено завдяки Lil 'Bits та ETHproductions, вони помітили, що я забув скоротити імена func та var.
32 байти, збережені завдяки RogerSpielker, він помітив, що я роблю просторовий код без причини; і знову -2 байти: onkeydown-> onkeyup
1 байт збережено: немає необхідності в остаточному
нахилі 2 байти збережені завдяки CraigAyre: with()функція
2 байта збережена завдяки ASCII лише: keyзамість which
4 байтів збережено, оскільки у нас є текст, немає потреби для '-'+(кожен ідентифікатор унікальний без цього) 1 байт збережений завдяки лише ASCII (знову ж таки): більше жодного символу закриття > 15 байт збережено завдяки апсилерам, як сказано вгорі моєї відповіді.

<body onkeyup=alert(event.code)


Зачекайте ... як виявлено ... Caps Lock ... виявлено? Я думав, що це неможливо ... Так, добре. PrtScn і SysRq не працюють для мене, але я на ноутбуці з невеликою клавіатурою, яка використовує Fn + End і Fn + Home для цих двох клавіш.
ETHproductions

Мені подобається ця відповідь, але, схоже, є деякі проблеми. Коли я перевіряю це на вкладці codepen.io/anon/pen/MoLPQM, Tab нічого не повідомляє . Також 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, всі інші - це лише звичайні ключі

6

Bash з X.org, 21 байт

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

На жаль, я не можу перевірити це, оскільки я перебуваю на MacBook в Linux - немає PrntScr, немає цифрової клавіатури тощо.

xevце інструмент, який виводить події миші та клавіатури під X.org. Я передаваю це, щоб пробудити, фільтрувати рівні лінії (оскільки кожна клавіша відображається при натисканні клавіші, а потім, коли вона відпущена), і вибираю лише ті, що містять (k- ця рядок є у кожному рядку, що описує натиснуту клавішу.


Чи можете ви додати приклади результатів, перелічених у запитанні, будь ласка.

1
@Lembik весь вихід з’являється після виходу.
enedil

Ага. Цього не вимагає специфікація. Я зрозумію, що зараз.

Це дає синтаксичну помилку зараз.

3
Зауважте, що Linux не передбачає X11. наприклад, це не працює на текстовій консолі (використовується showkey -sтам: P) або на чистому робочому столі Wayland GUI. Це справді баш + відповідь 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, зменшена до 9 елементів

-3: використовувати неявне intdecl для масиву даних wndclass

-8: видаліть новий рядок із вихідного формату (не потрібно в специфікації та printf спалахує відразу без нього); перейти RegisterClassв CreateWindowаргумент, використовуючи повернуті ATOM; встановіть ім'я wndclass, mякому просто потрібен нульовий байт, щоб він був дійсним рядком.

-3: повторне використання wvar для MSGданих


Зробити те ж саме з C ++ за допомогою cout не було б набагато коротше?
onurcanbektas

@Leth No. <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слід зберегти деякі.
ugoren

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
Введіть: 81
Введіть на NumPad: 84
Ліва клавіша Super: 193 (Після відключення ярлика меню для мого робочого столу)
Права клавіша Super: 201
Вставка: 241
Вставити на Numpad: 522948 (у мене немає, але це те, що ви отримуєте, коли натискаєте 5 із вимкненим Num lock. Коли Num lock увімкнено, ви отримуєте 812.)

Недоліковані / Пояснення:

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
    }
}

Не схоже, що це працює для клавіші вкладки?
Поп

setFocusTraversalKeysEnabled(false);у вашій відповіді це виправлю.
Magic Octopus Urn

@MagicOctopusUrn Я не знаю, що це робить, і не думаю, що хочу: P
musicman523

Це змушує вашу відповідь працювати за клавішею TAB, оскільки вона відповідає, що без неї відповідь недійсна.
Чарівна восьминога урна

Ohhhhh I see - Tab - "ключ
проходу

3

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

Зараз це відповідь масштабу :), навіть незважаючи на те, що я роблю 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) keyPress, "-", а потім його "розташування".

Наприклад :

PrtScn -> не перевіряється
Блокування прокрутки -> 145-1
Призупинення -> 19-1
Зміна ліворуч -> 16-2
Зміна праворуч -> 16-3
ліворуч Ctrl -> 17-2
праворуч Ctrl -> 17-3
Caps Lock -> 20-1
Tab -> не перевіряється
Введіть -> 10-1
Введіть на цифровій клавіатурі -> 10-4
Блокування чисел -> 144-4
Вставка -> 96-1
Ins на цифровій панелі -> 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

Хоча я думаю, це залежить від комп'ютера: / Я зараз на ноутбуці azerty.


Якщо ви хочете не рахувати зайвих декларацій, можливо, вам доведеться вказати довжину нестандартних прапорів компілятора. Якщо старі компілятори раніше не використовували це? Відповіді на C зазвичай потрібно складати, -std=c89оскільки сучасні компілятори за замовчуванням мають значення c99 або c11, але не потрібно вважати це. Тож я не впевнений, якою буде постанова щодо мета-коду-гольфу.
Пітер Кордес

3

TI-BASIC, 19 байт

ПРОГРАМА: S

If Ans
Disp Ans
getKey
prgmS
  • Введіть: 105,
  • Ліва клавіша: 24,
  • Права клавіша: 26,
  • У Inster є дещо іншим, тому що зазвичай потрібно два натискання клавіш, але це буде 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.


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;}}}

Виходи:

  • Вкладка: 137
  • Призупинення: 147
  • Введіть: 141
  • NumPad Enter: 142
  • Зліва Windows: 220
  • Права Windows: 221
  • Вставити: 174
  • Вставка NumPad: 224

Я можу трохи опустити байтів, змінившись ||на |інші подібні гольфи, але моєму мозку потрібен відпочинок після цього!
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.

Так що це має робити добре.


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 байти . Простий спосіб вбити програму (без таскмгр) - за допомогою 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

Виходи на тій же лінії, що і вхід, що може бути незрозумілим.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.