Welche Taste habe ich gedrückt?

15

Die Aufgabe besteht darin, Code zu schreiben, um zu identifizieren, welche Taste auf der Tastatur gedrückt wird. Sie können davon ausgehen, dass jeweils nur eine Taste gedrückt wird und dass ein standardmäßiges US-Tastaturlayout vorliegt. Das ist das Layout mit dem @ über dem 2.

Ihr Code sollte eine eindeutige Kennung für jede gedrückte Taste ausgeben. Dies umfasst PrtScn, Bildlaufsperre, Pause, linke Umschalttaste, rechte Umschalttaste, linke Strg-Taste, rechte Strg-Taste, Feststelltaste, Tabulator, Eingabetaste, Eingabetaste auf dem Nummernblock, Nummerntaste, Einfügen, Einfg auf dem Nummernblock, Rücktaste, Entf, F1 ... F12, Esc, linke Windows-Taste, rechte Windows-Taste, Alt, AltGr, Anwendungstaste (Kontextmenü) und so weiter.

Ihr Code sollte weiterhin auf Tastendruck warten und seine Identität ausgeben, bis er getötet wird. Es sollte jedoch die Kennung ausgeben, sobald eine Taste losgelassen wird. Es sollte keine andere Aktion von den Tastendrücken ausführen, die es empfängt, und es sollte nichts außer der eindeutigen Kennung ausgeben.

Zeigen Sie in Ihrer Antwort, was Sie für die folgenden Tastendrücke ausgeben: Tab, Pause, Eingabe, Eingabe auf dem Ziffernblock, linke Windows-Taste, rechte Windows-Taste, Einfügen und Einfügen auf dem Ziffernblock.

Wenn Sie eine ganz andere Tastatur haben, besteht die Herausforderung immer noch darin, für jede einzelne Taste Ihrer Tastatur eine andere Kennung auszugeben.


quelle
1
In JS (Browser JS) kann nicht überprüft werden, ob bestimmte Tasten gedrückt wurden (z. B. Feststelltaste, Num-Taste, Bildlaufsperre, Druck). Bedeutet das, dass JS nicht antworten kann?
ETHproductions
2
@ETHproductions Das tut es in der Tat. Entschuldigung an alle JS-Liebhaber.
2
Anforderungen, die nach 5 Antworten geändert wurden, werden bereitgestellt (einschließlich einer jetzt gelöschten). Das ist nicht wirklich fair ...
Olivier Grégoire
6
Ich halte es nicht für fair / richtig, Ausgaben für Tasten anzufordern, die nicht auf vielen Tastaturen wie Windows-Tasten usw. vorhanden sind
Notts90
1
@ Notts90 Gehören sie nicht zum Standard-Tastaturlayout der USA? upload.wikimedia.org/wikipedia/commons/thumb/5/51/…

Antworten:

22

x86-Maschinencode, ausführbare DOS-Datei, 29 * 28 Byte

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Dies ist eine ausführbare COM-Datei für MS-DOS , für die eine IBM PC-kompatible Hardware erforderlich ist .
Besonders ein 8042 PS / 2 Controller oder eher eine Emulation davon durch SMM .
Um es kurz zu machen, es sollte in jedem Mainstream-PC sofort funktionieren.

Der Quellcode ist

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

Ich habe das Programm in zwei Teile geteilt.

Der erste Teil befasst sich mit dem Lesen der Scancodes . Scancodes sind numerische Werte, die jedem Schlüssel zugeordnet sind.
Beachten Sie, dass dies Hardware-Code ist und nicht vom Betriebssystem oder dem Zeichensatz abhängt. Sie sind wie ein codiertes Paar (Spalte, Zeile) des Schlüssels.
Jede Taste hat einen Scancode, auch die ungewöhnlichen Funktionstasten, die auf einer Tastatur zu finden sind (z. B. die "Open Calc" -Taste).
Einige Schlüssel haben Multibyte-Scancode, sie haben Präfixe, mit denen der Stream nur anhand der Bytefolge dekodiert werden kann.
So erhält jede Taste eine eindeutige Kennung, sogar STRG, UMSCHALT, WinKeys und so weiter.

Es werden nur die "Break Codes" verarbeitet, die beim Loslassen eines Schlüssels gesendet werden. Die "Make Codes" werden ignoriert.
Die Former haben das höhere Bit (Bit 7 für ein Byte) gesetzt, so dass es leicht zu erkennen ist.

Der zweite Teil befasst sich mit dem Drucken eines Bytes.
Der Druck ist in der Montage immer langwierig, wir haben keine eingebauten.
Um es kurz zu halten, und da war es erforderlich zu schreiben eine Kennung des Schlüssels , habe ich Dezimal- oder Hexadezimalzahlen zugunsten einer persönlichen Kodierung aufgegeben.

Ein Byte xy, wobei x das höhere Halbbyte und y das niedrigere ist, wird als zwei aufeinanderfolgende Zeichen c 0 und c 1 gedruckt, die wie folgt definiert sind:

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

Beachten Sie, dass der untere Teil zuerst gedruckt wird (dies ersparte mir einen Tausch).
Das Grundprinzip besteht darin, jeden der 16 möglichen Werte eines Halbbytes in aufeinanderfolgende ASCII-Zeichen von '!' Abzubilden.
Einfach ausgedrückt ist dies eine Hex-Zahl, aber mit

  1. Die Knabbereien tauschten sich aus
  2. !"#$%&'()*+,-./01 als Ziffer (als) statt 0123456789abcdef

Wenn Sie es in DOSBox ausführen und eine zufällige Taste drücken (von denen einige eine spezielle Taste ist, beachten Sie jedoch, dass DOSBox als Windows-Prozess nicht alle Tasten erfassen kann), werden die Ergebnisse erzielt

DOSBox mit der Schlüsselkennung

Beachten Sie, dass dieses Programm niemals beendet wird (außerdem übernimmt es die vollständige Kontrolle über den PC, indem die Interrupts deaktiviert werden), wie ich es von der Frage gewollt habe (es gibt einfach kein Beenden von Prozessen unter DOS).


* Dank CodyGray reduziert .

Margaret Bloom
quelle
Hat sich herausgestellt, dass die Verwendung des INBefehls in Bezug auf Bytes kleiner ist als das Aufrufen der ROM-BIOS-Interrupts (z. B. int 16hFunktion 10h)?
Cody Grey
@CodyGray Wahrscheinlich nicht, die gesamte Schleife könnte übersprungen werden. Irgendwie bin ich gerade direkt zur inAnweisung gesprungen . Das ist eigentlich ein sehr guter Punkt, den Sie haben. Wenn Sie es noch nicht getan haben, warum veröffentlichen Sie es nicht als Antwort? :)
Margaret Bloom
1
Nun, jetzt redest du verrückt! Das hört sich nach viel mehr Arbeit an, als nur Ihre bestehende Antwort zu kommentieren. :-p Ich spiele damit, etwas zusammenzusetzen. Ein lustiger Tipp: Beim Code-Golfen ist xchgder Akku eines der Register 1 Byte, das ist also besser als ein 2-Byte mov.
Cody Grey
1
Okay, das Problem dabei int 16hist, dass ich keine Scan-Codes für die Umschalttasten, die Bildlaufsperre oder Pause / Pause (möglicherweise andere) erhalte, und das ist für die Herausforderung erforderlich. Ihre Lösung, die Eingabe direkt von der E / A zu lesen, funktioniert, obwohl sie für mich den gleichen Wert für alle Schlüssel im Cluster Ins / Del / Home / End / PgUp / PgDown zurückgibt.
Cody Grey
1
@PeterCordes: auch PAUSE hat ein seltsames Verhalten, IIUC sendet den Break-Code zusammen mit dem Make-Code beim Drücken der Taste und sendet nichts beim Loslassen der Taste. Oder das habe ich aus der PC Game Programming Encyclopedia verstanden.
Ninjalj
12

Java 7 oder höher, 246 228 Bytes

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 dank @ OlivierGrégoire für show(), 0<0undimport java.awt.event.*;

Was in ... endet:

Bildbeschreibung hier eingeben

Sogar das Drücken der Umschalttaste für Großbuchstaben, die Windows-Taste, die Feststelltaste usw. wird ausgeführt. Sie können sehen, dass auch die Modifikatoren gedruckt werden, bei denen es sich um gehaltene Tasten handelt.

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
Magische Kraken-Urne
quelle
Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Dennis
11

HTML (mit Javascript), 46 31 Zeichen, 46 31 Bytes

Verwenden Sie dies , um die Eingabe und Rückgabe von Nummernblöcken, LControl und RControl zu unterscheiden ... Nicht mehr, da Apsillers einen Weg gefunden haben, dies mit einem signle-Funktionsaufruf zu tun.

<body onkeyup=alert(event.code)

Spezifische Ausgänge:

AUSGABEN, DIE NOCH MIT DEN ZAHLEN SIND, KANN ICH NICHT AUF MEINEM LAPTOP PRÜFEN
BITTE, HABE

PrtScn -> PrintScreen
Scroll Lock -> ScrollLock
Pause -> Pause
links Shift -> ShiftLeft
rechts Shift -> ShiftRight
links Ctrl -> ContrlLeft
rechts Ctrl -> ControlRight
Caps Lock -> CapsLock
Tab -> Tab
Enter -> Enter
Enter für die Nummer pad -> NumpadEnter
Num Lock -> NumLock
Insert -> Insert
Ins auf dem Nummernblock -> Numpad0
Backspace -> Backspace
Del -> Löschen
F1 ... F12 -> F1 bis F12
Esc -> Escape
left Windows key -> MetaLeft application Taste (Kontextmenü) -> Kontextmenü
right Windows-Taste -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (Art Buggy, es erkennt ControlLeft und dann AltRight,aber es ist in der Tat AltRight)

EDITs:
1 Byte gespart, ;nachdem der Funk-Aufruf
18 Byte gespart hat, dank Lil 'Bits und ETHproductions. Sie haben bemerkt, dass ich vergessen habe, Funk- und Var-Namen zu kürzen.
Dank RogerSpielker konnten 32 Bytes eingespart werden. Er bemerkte, dass ich ohne Grund getrennten Code ausführte. und wieder -2 Bytes: onkeydown-> onkeyup
1 Byte gespeichert: kein abschließender Schrägstrich erforderlich
2 Bytes gespeichert dank CraigAyre: with()Funktion
2 Bytes gespeichert dank ASCII-only: keyanstelle von which
4 Bytes gespeichert, da wir Text haben, besteht keine Notwendigkeit für '-'+(jeder Bezeichner ist ohne dies einzigartig) 1 Byte gespeichert dank nur ASCII (wieder): kein schließendes Symbol mehr > 15 Bytes gespeichert dank Apsilierern, wie oben in meiner Antwort erwähnt.

<body onkeyup=alert(event.code)

V. Courtois
quelle
Warten Sie ... wie wird ... Feststelltaste ... erkannt? Ich dachte, das wäre unmöglich ... Na ja. PrtScn und SysRq funktionieren bei mir nicht, aber ich sitze auf einem Laptop mit einer kleinen Tastatur, die für diese beiden Tasten Fn + End und Fn + Home verwendet.
ETHproductions
Ich mag diese Antwort, aber sie scheint einige Probleme zu haben. Tab meldet nichts für mich, wenn ich es unter codepen.io/anon/pen/MoLPQM teste . Auch F12, PrtScn befolgen diese Regel nicht. "Es sollte keine andere Aktion von den eingegangenen Tastendrücken ausführen und nichts außer der eindeutigen Kennung ausgeben."
@Lembik mit HTML ist es nicht wirklich möglich zu verhindern, dass das System den Schlüssel verwendet. Sie müssen ihn zwingen, Tastatureingaben mit einer maschinen- (oder system-) wirksamen Sprache (wie C vielleicht) nicht zu erkennen. Und für Tab, ich weiß nicht, welche Bedingungen es für die Arbeit (ich meine, es funktioniert manchmal und manchmal nicht, ich weiß nicht, wie meine Antwort überquerbare Schlüssel behandelt.
V. Courtois
@Lembik Wenn Sie den Code in einem eigenständigen Format (kein Snippet oder Fiddle oder ähnliches) oder auf einer Vollbildseite (z. B. mit F11) anzeigen, werden Tabulatoren erfasst. Die Tatsache, dass keine Registerkarten erfasst werden, ist eine Funktion des Status einer größeren Browserumgebung und nicht des Codes, der auf der Seite ausgeführt wird. Was das Verhindern von Standardverhalten <body onkeydown=return!!alert(event.code)>falsekeydown
angeht
8

Tcl / Tk, 22 Zeichen

bind . <Key> {puts %K}

Probelauf:

Schlüssel identifiziert mit Tcl / Tk

Anmerkungen:

  • Kein Recht Windows - Taste auf meiner Tastatur ☹ ( clevere Designer hat den Schalter für die Hintergrundbeleuchtung eingesetzt)
  • Das Insert des Ziffernblocks generiert je nach NumLock-Status einen anderen Code
  • Der Lautstärkeregler generiert X.org-spezifische Codes, alle anderen sind nur normale Keysyms
Mann bei der Arbeit
quelle
6

Bash mit X.org, 21 Bytes

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

Leider kann ich es nicht testen, da ich unter Linux ein MacBook besitze - kein PrntScr, keine numerische Tastatur und alles.

xevist ein Tool, das Maus- und Tastaturereignisse ausgibt X.org. Ich leite es an awk weiter, filtere gerade Zeilen (da jede Taste beim Drücken und dann beim Loslassen angezeigt wird) und wähle nur diejenigen aus, die enthalten (k- diese Zeichenfolge steht in jeder Zeile, die die gedrückte Taste beschreibt.

enedil
quelle
Könnten Sie bitte die in der Frage aufgelisteten Beispielausgaben hinzufügen?
1
@Lembik Alle Ausgaben werden nach dem Beenden angezeigt.
13.
Ah. Das verlangt die Spezifikation nicht. Ich werde das jetzt klären.
Dies führt jetzt zu einem Syntaxfehler.
3
Beachten Sie, dass Linux nicht X11 impliziert. Dies würde zB auf einer Textkonsole ( showkey -sdort verwenden: P) oder auf einem reinen Wayland-GUI-Desktop nicht funktionieren . Dies ist wirklich eine bash + Xorg Antwort.
Peter Cordes
5

C und Win32, 240 224 216 205 202 194 191 Bytes

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

Ausgänge

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

Erläuterung

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

Bearbeitungen

-16 danke an @ugoren

-8: geändert WNDCLASSinint Array, da alle 10 Mitglieder 4 Bytes sind

-11: Teilinitialisierung des wndclass-Datenarrays, reduziert auf 9 Elemente

-3: implizite Verwendung int Deklaration für wndclass-Datenarray

-8: Zeilenumbruch aus dem Ausgabeformat entfernen (nicht erforderlich in spec und printf wird sofort ohne diesen gelöscht); Bewegen Sie RegisterClasssich mit CreateWindowreturn in arg ATOM. setze wndclass name aufm den nur ein Null-Byte benötigt wird, um eine gültige Zeichenfolge zu sein.

-3: wvar für MSGDaten wiederverwenden

MooseBoys
quelle
Dasselbe mit C ++ unter Verwendung von cout zu tun, wäre nicht viel kürzer?
Onurcanbektas
@Leth No. <iostream>+ std::cout<<a^b<<"\n"ist länger. Außerdem müssten Sie die Rückgabetypen zu den Funktionsdeklarationen hinzufügen, und mdas kann nicht implizit sein int.
MooseBoys
Rette einen for(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
Charakter
Auch p(x,y,a,b)und (void*)psollte einige retten.
Ugoren
3

Java (OpenJDK 8) , 369 Byte

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

Dies kann nicht mit TIO ausgeführt werden, da es eine grafische Oberfläche verwendet, aber auf meinem Computer funktioniert.

Pause: 153
Eingabe: 81
Eingabe auf NumPad: 84
Linke Super-Taste: 193 (Nach dem Deaktivieren der Menüverknüpfung für meinen Desktop)
Richtiger Superschlüssel: 201
Einfügen: 241
Insert on Numpad: 522948 (Ich habe keine, aber das bekommen Sie, wenn Sie 5 mit deaktivierter Num-Taste drücken. Wenn die Num-Taste aktiviert ist, bekommen Sie 812.)

Ungolfed / Erklärung:

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
quelle
Sieht nicht so aus, als ob es für die Tabulatortaste funktioniert?
Poke
setFocusTraversalKeysEnabled(false);in Ihrer Antwort wird dies beheben.
Magic Octopus Urn
@MagicOctopusUrn Ich weiß nicht, was das tut und ich glaube nicht, dass ich will: P
musicman523
Dadurch funktioniert Ihre Antwort für die TAB-Taste, da Ihre Antwort ohne diese ungültig ist.
Magic Octopus Urn
Ohhhhh, ich verstehe - Tab ist ein "Focus Traversal Key"
musicman523
3

Scala 2.10+, 279 Zeichen, 279 Byte

Nun, das ist eine Scala-Antwort :), obwohl es sich anfühlt, als würde ich Java machen. Jedenfalls können wir es nicht mit TIO testen.

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

Es ist traurig, dass wir alle geerbten Methoden deklarieren müssen, auch wenn wir sie nicht verwenden: Kann ich sie aus der Byteanzahl entfernen, da einige Compiler-Flags es erlauben, sie nicht zu deklarieren?

Dies druckt (wie für meine HTML-Js-Antwort) die Taste gedrückt, "-" und dann seine "Position".

Zum Beispiel :

PrtScn -> nicht überprüfbar
Scroll Lock -> 145-1
Pause -> 19-1
links Shift -> 16-2
rechts Shift -> 16-3
links Ctrl -> 17-2
rechts Ctrl -> 17-3
Caps Lock -> 20-1
Tab -> nicht verifizierbar
Enter -> 10-1
Enter auf dem Nummernblock -> 10-4
Num Lock -> 144-4
Insert -> 96-1
Ins auf dem Nummernblock -> 96-4
Backspace -> 8-1
Entf -> 127-1
F1 ... F12 -> 112-1 bis 123-1
Esc -> 27-1
linke Windows-Taste -> 524-2
rechte Windows-Taste -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (Art von Buggy, erkennt 17-2 und dann 18-3,aber es ist in der Tat 18-3)
Anwendungsschlüssel (Kontextmenü) -> 525-1

Obwohl ich denke, dass es vom Computer abhängt: / Ich bin gerade auf einem Azerty-Laptop.

V. Courtois
quelle
Wenn Sie nicht benötigte Deklarationen nicht zählen möchten, müssen Sie möglicherweise die Länge der Nicht-Standard-Compiler-Flags angeben. Es sei denn, alte Compiler haben dies standardmäßig verwendet? C-Antworten müssen normalerweise kompiliert werden, -std=c89da moderne Compiler standardmäßig c99 oder c11 verwenden, dies muss jedoch nicht gezählt werden. Ich bin mir also nicht sicher, wie das Urteil aus Code-Golf-Meta lauten würde.
Peter Cordes
3

TI-BASIC, 19 Bytes

PROGRAMM: S

If Ans
Disp Ans
getKey
prgmS
  • Eingabe: 105,
  • Linke Taste: 24,
  • Rechter Schlüssel: 26,
  • Ins [ert] ist ein wenig anders, weil es normalerweise zwei Tastendrücke dauert, um zu gelangen, aber diese wären 21, gefolgt von 23.

Hier ist eine Illustration der restlichen Tasten:

Bildbeschreibung hier eingeben

Erläuterung:

PROGRAMM: S Der Editor zeigt den Namen oben neben dem Code an. der Name ist "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

Dies ist in Arnold C leider nicht möglich, so dass ich mich an TI-BASIC halten musste.

bearacuda13
quelle
1
Funktioniert es für jeden Schlüssel in diesem Bild? Wenn nicht, für welche Schlüssel schlägt es fehl?
2
Ja, es funktioniert für jede Taste mit Ausnahme der Einschalttaste, die zum Beenden des Programms reserviert ist, ohne dass eine Batterie aus dem Taschenrechner gezogen wird.
Bearacuda13
@ bearacuda13: Ich habe einen gleichwertigen Taschenrechner, den ich vor 18 Jahren gekauft habe und den ich jahrelang nicht kannte. Ich hatte es seit dem Ende der Universität (vor 11 Jahren), aber wer weiß ...
Sergiol
1

C #, 144 + 601 = 745 Bytes

Besteht aus zwei Klassen, konnte ich sie nicht erfolgreich zu einer Klasse zusammenfassen.

Hauptklasse:

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

Hakenklasse:

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

Ausgänge:

  • Tab: 137
  • Pause: 147
  • Eingeben: 141
  • NumPad Enter: 142
  • Linkes Windows: 220
  • Richtiges Windows: 221
  • Einfügen: 174
  • NumPad Insert: 224
TheLethalCoder
quelle
Ich kann das Bytes ein wenig nach unten bekommen , indem Sie ||auf |und anderen ähnlichen Golf spielen , aber mein Gehirn braucht eine Pause nach , das zu tun!
TheLethalCoder
In der Hook-Klasse public int v;public int c;public int f;könnte man wohl verkürzen aufpublic int v,c,f;
Fragezeichen
@QuestionMarks Gute Idee wird Golf spielen, wenn ich wieder an einen Computer
gehe
1

AutoHotkey , 26 Bytes

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

Kann nicht testen (nur Win), aber die MOption sagt

M: Geänderte Tastenanschläge wie Control-A bis Control-Z werden erkannt und transkribiert, wenn sie echten ASCII-Zeichen entsprechen.

Also sollte es gut gehen.

phil294
quelle
1

WinApi C ( gcc ), 156 Bytes

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

Dieses Programm druckt den Windows-Virtual-Key-Code aus, der jeder Tastatureingabe zugeordnet ist. Die \nin der printfFormat-Zeichenfolge ist optional (macht die Ausgabe jedoch benutzerfreundlich) und kann für eine Gesamtpunktzahl von 154 Bytes gelöscht werden . Eine einfache Möglichkeit, das Programm (ohne taskmgr) zu beenden, ist mit CTRL + PAUSE. Wenn Sie eine Tastatur mit einer Fn-Taste haben, kann dieses Programm diese nicht aufheben, da sie von Windows nicht einmal bemerkt wird.

  • Dank an MooseBoys Antwort für den #include <d3d.h>Trick und die Inspiration für das BYTEArray.

Das Programm mit lokalen Variablen, Lesbarkeit und ohne Compiler-Warnungen sieht folgendermaßen aus:

#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
quelle
1

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

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

Der Code erfasst Schlüssel, auch wenn der Fokus verloren geht.

In den folgenden Screenshots werden Leerzeichen zwischen den Ausgaben eingefügt (printf("%d ",j); zur besseren Lesbarkeit +1 Byte) aufgenommen:

Schlüssel-Screenshot

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

Der Code GetAsyncKeyStatefragt den Schlüsselstatus ab, ohne die Nachrichtenwarteschlange zu überprüfen, normalerweise in Echtzeit als bei anderen Benutzermodus-Ansätzen (außer DirectInput). Dieser Ansatz ist in Keyloggern weit verbreitet.

(j<16||j>18)filtert reguläre Strg / Alt / Shift. 16/17/18 wird immer dann ausgelöst, wenn eine der Tasten links oder rechts gedrückt wird, zusammen mit dem vom Standort angegebenen vTastenwert.

Keyu Gan
quelle
1

PowerShell, 34 Byte

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

Ausgänge in derselben Zeile wie der Eingang, was etwas verwirrend sein kann.

Gabriel Mills
quelle