Jakim klawiszem nacisnąłem?

15

Zadanie polega na napisaniu kodu identyfikującego naciśnięcie klawisza na klawiaturze. Możesz założyć, że jednocześnie naciśnięty jest tylko jeden klawisz i że istnieje standardowy układ klawiatury w USA. To jest układ z @ nad 2.

Kod powinien wyświetlać unikalny identyfikator każdego naciśniętego klawisza. Obejmuje to PrtScn, Scroll Lock, Pause, lewy Shift, prawy Shift, lewy Ctrl, prawy Ctrl, Caps Lock, Tab, Enter, Enter na klawiaturze numerycznej, Num Lock, Insert, Ins na klawiaturze numerycznej, Backspace, Del, F1 ... F12, Esc, lewy klawisz Windows, prawy klawisz Windows, Alt, AltGr, klucz aplikacji (menu kontekstowe) i tak dalej.

Twój kod powinien dalej czekać na naciśnięcia klawiszy i wyświetlać swoją tożsamość, dopóki nie zostanie zabity. Powinien jednak wypisać identyfikator, gdy tylko klucz zostanie zwolniony. Nie powinien wykonywać żadnych innych działań z otrzymywanych naciśnięć klawiszy i nie powinien generować niczego poza unikalnym identyfikatorem.

W odpowiedzi pokaż, co kodujesz, dla następujących naciśnięć klawiszy: Tab, Pauza, Enter, Enter na klawiaturze numerycznej, lewy klawisz Windows, prawy klawisz Windows, Wstaw i Ins na klawiaturze numerycznej.

Jeśli masz bardzo inną klawiaturę, wyzwaniem jest nadal wydawanie innego identyfikatora dla każdego klawisza na klawiaturze.


źródło
1
W JS (przeglądarka JS, w każdym razie) nie można sprawdzić, czy niektóre klawisze są wciśnięte (np. Caps Lock, Num Lock, Scroll Lock, PrtScn). Czy to oznacza, że ​​JS nie może odpowiedzieć?
ETHprodukcje
2
@ETHproductions Tak się dzieje. Przepraszam miłośników JS wszędzie.
2
Wymagania zmodyfikowane po otrzymaniu 5 odpowiedzi (w tym jedna już usunięta). To niesprawiedliwe ...
Olivier Grégoire,
6
Nie sądzę, że jest sprawiedliwe / słuszne żądanie wyjścia dla kluczy, których nie ma na wielu klawiaturach, takich jak klawisz Windows itp.
Notts90 jest na codidact.org
1
@ Notts90 Czyż nie są one częścią standardowego układu klawiatury w USA? upload.wikimedia.org/wikipedia/commons/thumb/5/51/…

Odpowiedzi:

22

kod maszynowy x86, plik wykonywalny DOS, 29 * 28 bajtów

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Jest to plik wykonywalny COM dla MS-DOS , wymaga sprzętu kompatybilnego z IBM PC .
W szczególności kontroler 8042 PS / 2 lub bardziej prawdopodobne jego emulacja przez SMM .
Krótko mówiąc, powinien działać od razu po wyjęciu z pudełka na każdym głównym komputerze.

Kod źródłowy to

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

Program podzieliłem na dwie części.

Pierwsza część dotyczy odczytu skancodów . Skancody to wartości liczbowe powiązane z każdym kluczem.
Pamiętaj, że są to kody sprzętowe, nie zależą one od systemu operacyjnego ani zestawu znaków. Są jak zakodowana para (kolumna, rząd) klucza.
Każdy klawisz ma skancode, nawet te niestandardowe dziwne klawisze funkcyjne, które można znaleźć na niektórych klawiaturach (np. Klawisz „open calc”).
Niektóre klucze mają wielobajtowe scancode, mają prefiksy zaprojektowane do dekodowalności strumienia, po prostu patrząc na sekwencję bajtów.
Tak więc każdy klucz otrzymuje swój unikalny identyfikator, nawet CTRL, SHIFT, WinKeys i tak dalej.

Przetwarzane są tylko „kody złamania”, wysyłane po zwolnieniu klucza, a „make kody” są ignorowane.
Formery mają ustawiony wyższy bit (bit 7 dla bajtu), więc łatwo je rozpoznać.

Druga część dotyczy drukowania bajtu.
Drukowanie jest zawsze długie w montażu, nie mamy żadnych wbudowanych funkcji.
Krótko mówiąc, a ponieważ trzeba było wpisać identyfikator klucza, zrezygnowałem z liczb dziesiętnych lub szesnastkowych na rzecz osobistego kodowania.

Bajt xy, gdzie x oznacza wyższą wartość, ay niższa jest drukowana jako dwa kolejne znaki c 0 i c 1 zdefiniowane jako:

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

Zauważ, że dolny skubek jest drukowany jako pierwszy (to oszczędzało mi wymiany).
Uzasadnieniem jest odwzorowanie każdej z 16 możliwych wartości skrawka na kolejne znaki ASCII z „!”.
Po prostu jest to liczba szesnastkowa, ale z

  1. Skubki zamieniły się
  2. !"#$%&'()*+,-./01 jako cyfra (als) zamiast 0123456789abcdef

Uruchomienie go w DOSBoxie i naciśnięcie losowego klawisza (z których część jest klawiszem specjalnym, ale należy pamiętać, że jako proces Windows DOSBox nie może przechwycić wszystkich kluczy) daje

DOSBox z uruchomionym identyfikatorem klucza

Zauważ, że ten program nigdy się nie kończy (ponadto przejmuje pełną kontrolę nad komputerem poprzez wyłączenie przerwań), jak sądzę, że było to zamierzone przez pytanie (po prostu nie ma zabijania procesów w DOS).


* Zmniejszone podziękowania dla CodyGray .

Margaret Bloom
źródło
Czy użycie INinstrukcji okazało się mniejsze pod względem bajtów niż wywołanie przerwań ROM BIOS (np. int 16hFunkcja 10h)?
Cody Gray
@CodyGray Najprawdopodobniej nie, cała pętla może zostać pominięta. Jakoś właśnie skoczyłem prosto do ininstrukcji. To naprawdę bardzo dobra uwaga. Jeśli jeszcze tego nie zrobiłeś, dlaczego nie opublikować go jako odpowiedzi? :)
Margaret Bloom
1
Cóż, teraz mówisz szalony! Brzmi to o wiele więcej pracy niż komentowanie istniejącej odpowiedzi. :-p Gram ze składaniem czegoś. Zabawna wskazówka: podczas gry w golfa xchgz akumulatorem jako jednym z rejestrów jest 1 bajt, więc to lepiej niż 2 bajty mov.
Cody Gray
1
Okay, problem int 16hpolega na tym, że nie otrzymuję kodów skanowania dla klawiszy Shift, przewijania blokady lub pauzy / przerwy (być może innych), a to jest wymagane przez wyzwanie. Twoje rozwiązanie odczytu danych wejściowych bezpośrednio z I / O działa, chociaż wydaje mi się, że zwraca tę samą wartość dla wszystkich kluczy w klastrze Ins / Del / Home / End / PgUp / PgDown.
Cody Gray
1
@PeterCordes: również PAUZA ma dziwne zachowanie, IIUC wysyła kod przerwania wraz z kodem make po naciśnięciu klawisza i nie wysyła niczego po zwolnieniu klawisza. Albo to zrozumiałem z Encyklopedii programowania gier komputerowych.
ninjalj
12

Java 7 lub nowsza, 246 228 bajtów

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

Nie golfowany:

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 dzięki @ OlivierGrégoire do show(), 0<0iimport java.awt.event.*;

Co skutkuje w:

enter image description here

Nawet obsługuje naciśnięcia klawisza Shift dla wielkich liter, klawisza Windows, Caps Lock itp. Możesz zobaczyć, że drukuje również „modyfikatory”, które są „trzymanymi klawiszami”.

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
Urna Magicznej Ośmiornicy
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Dennis
11

HTML (z Javascriptem), 46 31 znaków, 46 31 bajtów

Używając tego do rozróżnienia wchodzenia i powrotu Numpada, LControl i RControl ... Już nie, ponieważ apsillery znaleźli sposób na zrobienie tego za pomocą wywołania funkcji signle.

<body onkeyup=alert(event.code)

Określone wyniki:

WYJŚCIA, KTÓRE WCIĄŻ SĄ Z NUMERAMI, KTÓRE NIE MOGĘ TESTOWAĆ NA MOIM LAPTOPIE
PROSZĘ CZEKAĆ NA MNIE

PrtScn -> PrintScreen
Scroll Lock -> ScrollLock
Pause -> Pause
left Shift -> ShiftLeft
right Shift -> ShiftRight
left Ctrl -> ContrlLeft
right Ctrl -> ControlRight
Caps Lock -> CapsLock
Tab -> Tab
Enter -> Enter
Enter on the number pad -> NumpadEnter
Num Lock -> NumLock
Insert -> Insert
Ins na klawiaturze numerycznej -> Numpad0
Backspace -> Backspace
Del -> Usuń
F1 ... F12 -> F1 do F12
Esc -> Escape
lewy klawisz Windows -> MetaLeft
prawy Klawisz Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (rodzaj błędu, wykrywa ControlLeft, a następnie AltRight,ale tak naprawdę jest AltRight)
klawisz aplikacji (menu kontekstowe) -> Menu kontekstowe

EDYCJE:
1 bajt zapisany ;po wywołaniu func
18 bajtów zapisanych dzięki Lil 'Bits i produktom ETH, zauważyli, że zapomniałem skracać nazwy func i var.
32 bajty zaoszczędzone dzięki RogerSpielker, zauważył, że robię sparowany kod bez powodu; i ponownie -2 bajty: onkeydown-> onkeyup
1 bajt zapisany: nie ma potrzeby końcowego ukośnika
2 bajty zapisane dzięki CraigAyre: with()funkcja
2 bajty zapisane tylko dzięki ASCII: keyzamiast which
4 bajtów zapisanych, ponieważ mamy tekst, nie ma potrzeby bo '-'+(bez tego każdy identyfikator jest unikalny) 1 bajt zapisany dzięki tylko ASCII (ponownie): > koniec z zapisem 15 bajtów zapisanych dzięki apsillerom, jak powiedziano na górze mojej odpowiedzi.

<body onkeyup=alert(event.code)

V. Courtois
źródło
Poczekaj ... w jaki sposób wykrywa się ... Caps Lock ...? Myślałem, że to niemożliwe ... No cóż. PrtScn i SysRq nie działają dla mnie, ale jestem na laptopie z małą klawiaturą, która używa Fn + End i Fn + Home dla tych dwóch klawiszy.
ETHprodukcje
Podoba mi się ta odpowiedź, ale wydaje się, że ma pewne problemy. Tab nic mi nie zgłasza, gdy testuję to na codepen.io/anon/pen/MoLPQM . Również F12, PrtScn nie przestrzegają tej zasady: „Nie powinien wykonywać żadnych innych działań po naciśnięciach klawiszy, które otrzymuje i nie powinien generować niczego poza unikalnym identyfikatorem”.
@Lembik przy użyciu html, tak naprawdę nie jest możliwe, aby system nie używał klucza. Musisz wymusić, aby nie rozpoznawał kluczowych danych wejściowych za pomocą efektywnego języka maszyny (lub systemu) (na przykład C). A jeśli chodzi o zakładkę, nie wiem, jakie są warunki jej pracy (mam na myśli, że czasami działa, a czasem nie, nie wiem, jak moja odpowiedź traktuje klucze, które można przechodzić.
V. Courtois,
@Lembik Jeśli przeglądasz kod w niezależnej (nie we fragmencie, skrzypce itp.), Stronie pełnoekranowej (np. Z klawiszem F11), wówczas przechwytuje tabulatory; fakt, że nie przechwytuje kart, jest funkcją stanu większego środowiska przeglądarki, a nie kodu uruchamianego na stronie. Jeśli chodzi o zapobieganie zachowaniom domyślnym, <body onkeydown=return!!alert(event.code)>powinieneś załatwić falsekeydown
sprawę,
8

Tcl / Tk, 22 znaki

bind . <Key> {puts %K}

Przykładowy przebieg:

keys identified by Tcl/Tk

Uwagi:

  • Brak prawego klawisza Windows na mojej klawiaturze ☹ ( sprytny projektant umieścił przełącznik podświetlenia na swoim miejscu)
  • Wstawka klawiatury numerycznej generuje inny kod na podstawie statusu NumLock
  • Pokrętło głośności generuje kody specyficzne dla X.org, wszystkie pozostałe są tylko zwykłymi kluczami
człowiek w pracy
źródło
6

Bash z X.org, 21 bajtów

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

Niestety nie mogę go przetestować, ponieważ korzystam z MacBooka w systemie Linux - bez PrntScr, bez klawiatury numerycznej i wszystkich innych.

xevto narzędzie, które wyświetla zdarzenia myszy i klawiatury X.org. Przeciągam potokiem do awk, filtruję nawet linie (ponieważ każdy klawisz jest wyświetlany po naciśnięciu klawisza, a następnie po zwolnieniu) i wybieram tylko te, które zawierają (k- ten ciąg znajduje się w każdej linii opisującej wciśnięty klawisz.

enedil
źródło
Czy możesz dodać przykładowe dane wyjściowe wymienione w pytaniu?
1
@Lembik wszystkie dane wyjściowe pojawiają się po wyjściu.
enedil
Ach Nie tego wymaga specyfikacja. Wyjaśnię to teraz.
Daje to teraz błąd składniowy.
3
Zauważ, że Linux nie oznacza X11. np. nie działałoby to na konsoli tekstowej (użyj showkey -stam: P) lub na czystym pulpicie GUI Wayland. To naprawdę bash + odpowiedź Xorga.
Peter Cordes
5

C i Win32, 240 224 216 205 202 194 191 bajtów

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

Wyjścia

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

Wyjaśnienie

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

Edycje

-16 dzięki @ugoren

-8: zmieniono WNDCLASSna inttablicę, ponieważ wszystkie 10 elementów ma 4 bajty

-11: częściowa inicjalizacja tablicy danych wndclass, zmniejszona do 9 elementów

-3: użyj niejawnej intdeklaracji dla tablicy danych wndclass

-8: usuń znak nowej linii z formatu wyjściowego (niewymagane w specyfikacji i od razu opróżnia printf bez niego); przejdź RegisterClassdo CreateWindowarg, używając return ATOM; ustaw nazwę wndclass, na mktórą wystarczy zero bajtów, aby być poprawnym ciągiem.

-3: ponownie wużyj var dla MSGdanych

MooseBoys
źródło
Robienie tego samego z C ++ przy użyciu cout nie byłoby znacznie krótsze?
onurcanbektas
@ Let No. <iostream>+ std::cout<<a^b<<"\n"jest dłuższy. Ponadto myślę, że trzeba dodać typy zwracane do deklaracji funkcji i mnie może to być niejawne int.
MooseBoys
Uratuj postać zfor(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
ugoren
Również p(x,y,a,b)i (void*)ppowinien oszczędzić trochę.
ugoren
3

Java (OpenJDK 8) , 369 bajtów

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

Nie można tego uruchomić z TIO, ponieważ używa interfejsu graficznego, ale działa na moim komputerze.

Pauza: 153
Wpisz: 81
Wpisz na NumPad: 84
Lewy super klawisz: 193 (po wyłączeniu skrótu Menu na pulpicie)
Prawy superklucz: 201
Wstaw: 241
Wstaw na Numpad: 522948 (Nie mam, ale to dostajesz, gdy naciśniesz 5 przy wyłączonej Num lock. Gdy Num Lock jest włączony, otrzymasz 812.)

Niegolfowane / Objaśnienie:

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
źródło
Nie wygląda na to, że działa z klawiszem Tab?
Poke
setFocusTraversalKeysEnabled(false);w twojej odpowiedzi to naprawi.
Magic Octopus Urn
@MagicOctopusUrn Nie wiem, co to robi i nie sądzę, żebym chciał: P
musicman523,
Sprawia, że ​​twoja odpowiedź działa dla klawisza TAB, ponieważ oznacza to, że bez niej odpowiedź jest nieprawidłowa.
Magic Octopus Urn
Ohhhhh Rozumiem - Tab to „klucz przejścia przez fokus”
musicman523,
3

Scala 2.10+, 279 znaków, 279 bajtów

To jest odpowiedź SCALA :) mimo że wydaje mi się, że robię Java. W każdym razie nie możemy przetestować tego na 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){}})}}

To smutne, że musimy zadeklarować wszystkie odziedziczone metody, nawet jeśli ich nie używamy: czy mogę je usunąć z liczby bajtów, ponieważ niektóre flagi kompilatora mogą pozwolić na ich nie deklarowanie?

Spowoduje to wydrukowanie (jak w przypadku mojej odpowiedzi HTML-js) keyPressed, „-”, a następnie jego „lokalizacji”.

Na przykład :

PrtScn -> nie można zweryfikować
Scroll Lock -> 145-1
Pauza -> 19-1
lewy Shift -> 16-2
prawy Shift -> 16-3
lewy Ctrl -> 17-2
prawy Ctrl -> 17-3
Caps Lock -> 20-1
Tab -> nieweryfikowalny
Enter -> 10-1
Enter na klawiaturze numerycznej -> 10-4
Num Lock -> 144-4
Insert -> 96-1
Ins na klawiaturze numerycznej -> 96-4
Backspace -> 8-1
Del -> 127-1
F1 ... F12 -> 112-1 do 123-1
Esc -> 27-1
lewy klawisz Windows -> 524-2
prawy klawisz Windows -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (rodzaj buggy, wykrywa 17-2, a następnie 18-3,ale tak naprawdę jest to 18-3)
klucz aplikacji (menu kontekstowe) -> 525-1

Chociaż myślę, że to zależy od komputera: / Jestem teraz na laptopie Azerty.

V. Courtois
źródło
Jeśli nie chcesz liczyć niepotrzebnych deklaracji, konieczne może być podanie długości niestandardowych flag kompilatora. Chyba że stare kompilatory używały tego domyślnie? Zazwyczaj trzeba skompilować odpowiedzi w języku C, -std=c89ponieważ współczesne kompilatory mają domyślnie c99 lub c11, ale nie trzeba tego liczyć. Więc nie jestem pewien, jaka byłaby decyzja z meta-golfa.
Peter Cordes
3

TI-BASIC, 19 bajtów

PROGRAM: S

If Ans
Disp Ans
getKey
prgmS
  • Wpisz: 105,
  • Lewy klawisz: 24,
  • Prawy klawisz: 26,
  • Ins [ert] jest trochę inny, ponieważ normalnie potrzeba dwóch naciśnięć klawiszy, ale są to 21, a następnie 23.

Oto ilustracja pozostałych kluczy:

wprowadź opis zdjęcia tutaj

Wyjaśnienie:

PROGRAM: S Edytor wyświetla nazwę u góry oprócz kodu; nazywa się „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

Niestety nie jest to możliwe w Arnold C, więc musiałem trzymać się TI-BASICA.

bearacuda13
źródło
1
Czy to działa z każdym kluczem na tym zdjęciu? Jeśli nie, dla których kluczy to nie działa?
2
Tak, działa z każdym klawiszem oprócz przycisku włączonego, zarezerwowanym do zabicia programu bez wyjęcia baterii z kalkulatora.
bearacuda13
@ bearacuda13: Mam kalkulator równości, który kupiłem 18 lat temu i od lat nie znałem kluczowych szczegółów ON.
Używałem
1

C #, 144 + 601 = 745 bajtów

Składa się z dwóch klas, nie udało mi się połączyć ich w jedną klasę.

Główna klasa:

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

Klasa haka:

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

Wyjścia:

  • Patka: 137
  • Pauza: 147
  • Wchodzić: 141
  • NumPad Enter: 142
  • Lewy Windows: 220
  • Właściwy system Windows: 221
  • Wstawić: 174
  • NumPad Insert: 224
TheLethalCoder
źródło
Mogę trochę obniżyć bajty, zmieniając się ||na |i inne podobne golfa, ale mój mózg potrzebuje odpoczynku po tym!
TheLethalCoder
W klasie Hook myślę, że public int v;public int c;public int f;można ją skrócić dopublic int v,c,f;
Znaki zapytania
@QuestionMarks Dobry pomysł zagra w golfa, gdy wrócę do komputera
TheLethalCoder
1

AutoHotkey , 26 bajtów

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

Nie można przetestować (tylko wygrana), ale M opcja mówi

M: Zmodyfikowane naciśnięcia klawiszy, takie jak Control-A do Control-Z, są rozpoznawane i transkrybowane, jeśli odpowiadają rzeczywistym znakom ASCII.

Więc powinno być dobrze.

phil294
źródło
1

WinApi C ( gcc ), 156 bajtów

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

Ten program drukuje kod wirtualnego klucza systemu Windows przypisany do każdego klawisza klawiatury. \nW printfformacie-string jest opcjonalne (ale sprawia, że wyjście ludzki w obsłudze) i może zostać usunięta za łączną notą 154 bajtów . Łatwym sposobem na zabicie programu (bez taskmgr) jest CTRL + PAUSE. Jeśli masz klawiaturę z klawiszem Fn, ten program nie może jej podnieść, ponieważ nie jest nawet zauważany przez system Windows.

  • Podziękowania dla odpowiedzi MooseBoys za #include <d3d.h>podstęp i inspirację dla BYTEtablicy.

Program ze zmiennymi lokalnymi, czytelnością i bez ostrzeżeń kompilatora wygląda następująco:

#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;
}
Sir Random
źródło
1

C (gcc) + Win32, 94 95 98 105 107 110 bajty

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

Kod przechwytuje klucze nawet po utracie ostrości.

Następujące zrzuty ekranu są rejestrowane, dodając spacje między wyjściami ( printf("%d ",j);+1 bajt) dla lepszej czytelności:

kluczowy zrzut ekranu

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

Kod używa GetAsyncKeyStatedo sprawdzania stanu klucza bez sprawdzania kolejki komunikatów, zwykle w czasie rzeczywistym bardziej niż inne podejścia w trybie użytkownika (z wyjątkiem DirectInput). To podejście jest szeroko stosowane w keyloggerach.

(j<16||j>18)filtruje zwykłe Ctrl / Alt / Shift. 16/17/18 jest uruchamiany za każdym razem, gdy zostanie naciśnięty lewy lub prawy przycisk, wraz z wartością vkey określoną dla lokalizacji.

Keyu Gan
źródło
1

PowerShell, 34 bajty

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

Wyjścia w tym samym wierszu co wejście, co może być nieco mylące.

Gabriel Mills
źródło