Sur quelle touche ai-je appuyé?

15

La tâche consiste à écrire du code pour identifier la touche enfoncée sur le clavier. Vous pouvez supposer qu'une seule touche est enfoncée à la fois et qu'il existe une disposition de clavier américaine standard. C'est la disposition avec le @ sur le 2.

Votre code doit générer un identifiant unique pour chaque touche enfoncée. Cela comprend PrtScn, Scroll Lock, Pause, gauche Shift, droite Shift, gauche Ctrl, droite Ctrl, Caps Lock, Tab, Enter, Enter sur le pavé numérique, Num Lock, Insert, Ins sur le pavé numérique, Backspace, Del, F1 ... F12, Esc, touche Windows gauche, touche Windows droite, Alt, AltGr, touche application (menu contextuel) et ainsi de suite.

Votre code doit continuer d'attendre les pressions sur les touches et de sortir leur identité jusqu'à ce qu'il soit tué. Cependant, il devrait sortir l'identifiant dès qu'une clé est relâchée. Il ne doit effectuer aucune autre action à partir des pressions sur les touches qu'il reçoit et il ne doit rien produire en dehors de l'identifiant unique.

Dans votre réponse, veuillez indiquer ce que vous codez les sorties pour les pressions de touches suivantes: Tab, Pause, Entrée, Entrée sur le pavé numérique, touche Windows gauche, touche Windows droite, Insérer et insérer sur le pavé numérique.

Si vous avez un clavier très différent, le défi est toujours de sortir un identifiant différent pour chaque touche de votre clavier.


la source
1
Dans JS (navigateur JS, de toute façon), il est impossible de vérifier si certaines touches sont enfoncées (par ex. Verrouillage des majuscules, verrouillage numérique, verrouillage du défilement, PrtScn). Est-ce à dire que JS ne peut pas répondre?
ETHproductions
2
@ETHproductions C'est effectivement le cas. Toutes mes excuses aux amoureux de JS partout.
2
Les exigences modifiées après 5 réponses sont fournies (dont une maintenant supprimée). Ce n'est pas vraiment juste ...
Olivier Grégoire
6
Je ne pense pas qu'il soit juste / juste de demander une sortie pour des clés qui ne sont pas sur de nombreux claviers tels que la clé Windows, etc.
Notts90 est hors de codidact.org
1
@ Notts90 Ne font-ils pas partie de la disposition standard du clavier américain? upload.wikimedia.org/wikipedia/commons/thumb/5/51/…

Réponses:

22

Code machine x86, exécutable DOS, 29 * 28 octets

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Il s'agit d'un exécutable COM pour MS-DOS , il nécessite un matériel compatible IBM PC .
En particulier un contrôleur 8042 PS / 2 ou plus probablement une émulation via SMM .
Pour faire court, il devrait fonctionner dès la sortie de la boîte sur n'importe quel PC ordinaire.

Le code source est

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

J'ai divisé le programme en deux parties.

La première partie traite de la lecture des scancodes . Les scancodes sont des valeurs numériques associées à chaque touche.
Notez que ce sont du code matériel, ils ne dépendent pas du système d'exploitation ou du jeu de caractères. Ils sont comme une paire codée (colonne, ligne) de la clé.
Chaque touche a un scancode, même ces touches de fonction étranges non standard trouvées sur certains claviers (par exemple la touche "open calc").
Certaines clés ont un scancode multi-octets, elles ont des préfixes conçus pour rendre le flux décodifiable en regardant simplement la séquence d'octets.
Ainsi, chaque clé obtient son identifiant unique, même CTRL, SHIFT, WinKeys et ainsi de suite.

Seuls les "codes de rupture", envoyés lorsqu'une touche est relâchée, sont traités, les "codes de création" sont ignorés.
Les formateurs ont le bit le plus élevé (bit 7 pour un octet), il est donc facile de les reconnaître.

La deuxième partie traite de l'impression d'un octet.
L'impression est toujours longue en assemblage, nous n'avons pas de fonctions intégrées.
Pour faire court, et comme il fallait écrire un identifiant de la clé, j'ai abandonné les chiffres décimaux ou hexadécimaux au profit d'un encodage personnel.

Un octet xy, où x est le quartet supérieur et y le plus petit est affiché sous la forme de deux caractères successifs c 0 et c 1 définis comme:

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

Notez que le quartet inférieur est imprimé en premier (cela m'a épargné un échange).
Le raisonnement est de mapper chacune des 16 valeurs possibles d'un quartet en caractères ASCII consécutifs à partir de '!'.
Autrement dit, c'est un chiffre hexadécimal, mais avec

  1. Les grignotages échangés
  2. !"#$%&'()*+,-./01 comme chiffre (als) au lieu de 0123456789abcdef

L' exécuter dans DOSBox et appuyer sur une touche aléatoire (dont certaines sont une clé spéciale mais notez qu'en tant que processus Windows, DOSBox ne peut pas capturer toutes les clés) donne

DOSBox exécutant l'identifiant de clé

Notez que ce programme ne se termine jamais (en outre, il prend le contrôle complet du PC en désactivant les interruptions) comme je pense que la question le voulait (simplement, il n'y a pas de destruction de processus sous DOS).


* Remerciements réduits à CodyGray .

Margaret Bloom
la source
Est-ce que l'utilisation de l' INinstruction s'est avérée plus petite en termes d'octets que d'appeler les interruptions du BIOS ROM (par exemple int 16h, fonction 10h)?
Cody Gray
@CodyGray Probablement pas, la boucle entière pourrait être sautée. D'une manière ou d'une autre, je suis passé directement à l' ininstruction. C'est en fait un très bon point que vous avez. Si vous ne l'avez pas déjà fait, pourquoi ne pas l'afficher comme réponse? :)
Margaret Bloom
1
Et bien maintenant tu parles de fou! Cela ressemble à beaucoup plus de travail que de simplement commenter votre réponse existante. :-p je joue avec mettre quelque chose ensemble. Astuce amusante, cependant: lorsque vous jouez au code, xchgl'accumulateur comme l'un des registres est de 1 octet, donc c'est mieux qu'un 2 octets mov.
Cody Grey
1
D'accord, le problème int 16hest que je n'obtiens pas de codes de numérisation pour les touches Maj, le verrouillage du défilement ou la pause / pause (peut-être d'autres), et cela est requis par le défi. Votre solution de lecture de l'entrée directement à partir des E / S fonctionne, bien qu'elle me semble renvoyer la même valeur pour toutes les clés du cluster Ins / Del / Home / End / PgUp / PgDown.
Cody Gray
1
@PeterCordes: PAUSE a également un comportement étrange, l'IIUC envoie le code de rupture avec le code de création à la pression de la touche et n'envoie rien lors de la libération de la touche. Ou c'est ce que j'ai compris de l'encyclopédie de programmation de jeux PC.
ninjalj
12

Java 7 ou supérieur, 246 228 octets

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

Non golfé:

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 merci à @ OlivierGrégoire pour show(), 0<0etimport java.awt.event.*;

Ce qui se traduit par:

entrez la description de l'image ici

Gère même les presses Maj pour les caractères en majuscule, la touche Windows, les verrous de majuscules, etc.

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
Urne de poulpe magique
la source
Les commentaires ne sont pas pour une discussion approfondie; cette conversation a été déplacée vers le chat .
Dennis
11

HTML (avec Javascript), 46 31 caractères, 46 31 octets

En utilisant cela pour différencier l'entrée et le retour du pavé numérique, LControl et RControl ... Plus depuis que les apsillers ont trouvé un moyen de le faire avec un appel de fonction de signalisation.

<body onkeyup=alert(event.code)

Sorties spécifiques:

LES SORTIES QUI SONT ENCORE AVEC LES CHIFFRES SONT CEUX QUE JE NE PEUX PAS TESTER SUR MON ORDINATEUR PORTABLE,
VEUILLEZ ATTENDRE QUE J'AI ACCÈS À CES CLÉS

PrtScn -> PrintScreen
Scroll Lock -> ScrollLock
Pause -> Pause
left Shift -> ShiftLeft
right Shift -> ShiftRight
left Ctrl -> ContrlLeft
right Ctrl -> ControlRight
Caps Lock ->
Tab LockLock -> Tab
Enter -> Enter
Entrez le numéro pavé numérique -> NumpadEnter
Num Lock -> NumLock
Insert -> Insert
Ins sur le pavé numérique -> Numpad0
Backspace -> Backspace
Del -> Delete
F1 ... F12 -> F1 to F12
Esc -> Escape
left Windows key -> MetaLeft
right Touche Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (sorte de buggy, il détecte ControlLeft puis AltRight,mais c'est bien AltRight)
clé d'application (menu contextuel) -> ContextMenu

EDITs:
1 octet enregistré ;après l'appel func
18 octets enregistrés grâce aux Lil 'Bits et aux productions ETH, ils ont remarqué que j'avais oublié de raccourcir les noms func et var.
32 octets économisés grâce à RogerSpielker, il a remarqué que je faisais du code épargné sans raison; et encore -2 octets: onkeydown-> onkeyup
1 octet enregistré: pas besoin de barre oblique finale
2 octets enregistrés grâce à CraigAyre: with()fonction
2 octets enregistrés grâce à ASCII uniquement: keyau lieu de which
4 octets enregistrés, puisque nous avons du texte, il n'y a pas besoin pour '-'+(chaque identifiant est unique sans cela) 1 octet enregistré grâce à ASCII uniquement (encore): plus de symbole de fermeture > 15 octets enregistrés grâce à apsillers, comme dit en haut de ma réponse.

<body onkeyup=alert(event.code)

V. Courtois
la source
Attendez ... comment ... le verrouillage des majuscules ... est-il détecté? Je pensais que c'était impossible ... Huh, eh bien. PrtScn et SysRq ne fonctionnent pas pour moi, mais je suis sur un ordinateur portable avec un petit clavier qui utilise Fn + End et Fn + Home pour ces deux touches.
ETHproductions
J'aime cette réponse mais elle semble avoir quelques problèmes. Tab ne rapporte rien pour moi lorsque je le teste sur codepen.io/anon/pen/MoLPQM . De plus, F12, PrtScn ne suit pas cette règle "Il ne doit effectuer aucune autre action à partir des pressions sur les touches qu'il reçoit et il ne doit rien sortir en dehors de l'identifiant unique."
@Lembik utilisant html, il n'est pas vraiment possible d'empêcher le système d'utiliser la clé. Vous devez le forcer à ne pas reconnaître les entrées clés avec un langage efficace machine (ou système) (comme C peut-être). Et pour tab, je ne sais pas quelles conditions cela fonctionne (je veux dire, cela fonctionne parfois et parfois non, je ne sais pas comment ma réponse traite les touches traversables.
V. Courtois
@Lembik Si vous affichez le code dans une page autonome (pas un extrait ou un violon ou similaire), en plein écran (par exemple, avec F11), il capture les onglets; le fait qu'il ne capture pas les onglets est fonction de l'état d'un environnement de navigateur plus grand, et non du code exécuté sur la page. En ce qui concerne la prévention des comportements par défaut, <body onkeydown=return!!alert(event.code)>devrait faire l'affaire en revenant falsesurkeydown
apsillers
8

Tcl / Tk, 22 caractères

bind . <Key> {puts %K}

Exemple d'exécution:

clés identifiées par Tcl / Tk

Remarques:

  • Pas de bonne touche Windows sur mon clavier ☹ ( un concepteur intelligent a mis le commutateur de rétroéclairage à sa place)
  • L'insertion du pavé numérique génère un code différent en fonction de l'état de NumLock
  • Le bouton de volume génère des codes spécifiques à X.org, tous les autres ne sont que des clés classiques
homme au travail
la source
6

Bash avec X.org, 21 octets

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

Malheureusement, je ne peux pas le tester car je suis sur MacBook sous Linux - pas de PrntScr, pas de clavier numérique et tout.

xevest un outil qui génère des événements de souris et de clavier sous X.org. Je le redirige vers awk, filtre les lignes paires (puisque chaque touche est affichée lorsque la touche est enfoncée, puis lorsqu'elle est relâchée), et sélectionne uniquement celles qui contiennent (k- cette chaîne se trouve dans chaque ligne qui décrit la touche enfoncée.

enedil
la source
Pourriez-vous ajouter les exemples de sorties répertoriés dans la question, s'il vous plaît.
1
@Lembik toutes les sorties apparaissent après la sortie.
enedil
Ah. Ce n'est pas ce que la spécification demande. Je vais clarifier cela maintenant.
Cela donne maintenant une erreur de syntaxe.
3
Notez que Linux n'implique pas X11. par exemple, cela ne fonctionnerait pas sur une console texte (utilisez showkey -s-la: P), ou sur un bureau GUI Wayland pur. C'est vraiment une réponse bash + Xorg.
Peter Cordes
5

C et Win32, 240 224 216 216 205 202 194 191 octets

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

Les sorties

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

Explication

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

Modifications

-16 grâce à @ugoren

-8: changé WNDCLASSen inttableau puisque les 10 membres font 4 octets

-11: initialisation partielle du tableau de données wndclass, réduite à 9 éléments

-3: utiliser le intdéclin implicite pour le tableau wndclass-data

-8: supprimer la nouvelle ligne du format de sortie (non requis dans les spécifications et les vidages printf immédiatement sans); passer RegisterClassà CreateWindowarg, en utilisant retourné ATOM; définissez le nom de la classe wnd surm qui n'a besoin que d'un octet zéro pour être une chaîne valide.

-3: réutiliser wvar pour les MSGdonnées

MooseBoys
la source
Faire la même chose avec C ++ en utilisant cout ne serait pas beaucoup plus court?
onurcanbektas
@Leth No. <iostream>+ std::cout<<a^b<<"\n"est plus long. De plus, je pense que vous auriez besoin d'ajouter des types de retour aux fonctions decls, et mne pourrait pas être implicite int.
MooseBoys
Enregistrer un personnage avecfor(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
Ugoren
Aussi, p(x,y,a,b)et (void*)pdevrait en sauver quelques-uns.
ugoren
3

Java (OpenJDK 8) , 369 octets

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

Cela ne peut pas être exécuté avec TIO car il utilise une interface graphique, mais cela fonctionne sur mon ordinateur.

Pause: 153
Entrez: 81
Entrez sur NumPad: 84
Touche Super gauche: 193 (après avoir désactivé le raccourci Menu pour mon bureau)
Touche Super droite: 201
Insérer: 241
Insérer sur le pavé numérique: 522948 (je n'en ai pas, mais c'est ce que vous obtenez lorsque vous appuyez sur 5 avec le verrouillage numérique désactivé. Lorsque le verrouillage numérique est activé, vous obtenez 812.)

Non golfé / Explication:

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
la source
Ne semble pas que cela fonctionne pour la touche de tabulation?
Poke
setFocusTraversalKeysEnabled(false);dans votre réponse va résoudre ce problème.
Magic Octopus Urn
@MagicOctopusUrn Je ne sais pas ce que cela fait et je ne pense pas que je veux: P
musicman523
Cela fait fonctionner votre réponse pour la touche TAB, car en l'état, votre réponse n'est pas valide sans elle.
Magic Octopus Urn
Ohhhhh je vois - Tab est une "touche de traversée de focus"
musicman523
3

Scala 2.10+, 279 caractères, 279 octets

Maintenant, c'est une réponse scala :) même si j'ai l'impression de faire Java. Quoi qu'il en soit, nous ne pouvons pas le tester sur 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){}})}}

C'est triste, nous devons déclarer toutes les méthodes héritées même si nous ne les utilisons pas: l puis-je les supprimer du nombre d'octets, car certains drapeaux du compilateur peuvent permettre de ne pas les déclarer?

Cela affiche (comme pour ma réponse html-js) le keyPressed, "-" puis son "emplacement".

Par exemple :

PrtScn -> non vérifiable
Scroll Lock -> 145-1
Pause -> 19-1
left Shift -> 16-2
right Shift -> 16-3
left Ctrl -> 17-2
right Ctrl -> 17-3
Caps Lock ->
Onglet 20-1 -> non vérifiable
Entrée -> 10-1
Entrée sur le pavé numérique -> 10-4
Verr Num -> 144-4
Insertion -> 96-1
Ins sur le pavé numérique -> 96-4
Retour arrière -> 8-1
Suppr -> 127-1
F1 ... F12 -> 112-1 à 123-1
Esc
-> 27-1 touche Windows gauche -> 524-2
touche Windows droite -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (sorte de buggy, il détecte 17-2 puis 18-3,mais c'est bien 18-3)
clé d'application (menu contextuel) -> 525-1

Bien que je pense que cela dépend de l'ordinateur: / Je suis actuellement sur un ordinateur portable azerty.

V. Courtois
la source
Si vous souhaitez ne pas compter les déclarations inutiles, vous devrez peut-être inclure la longueur des indicateurs de compilateur non standard. À moins que les anciens compilateurs ne le fassent par défaut? Les réponses C doivent généralement être compilées avec -std=c89car les compilateurs modernes sont par défaut c99 ou c11, mais n'ont pas besoin de compter cela. Donc, je ne sais pas quelle serait la décision de la méta-code-golf.
Peter Cordes
3

TI-BASIC, 19 octets

PROGRAMMES

If Ans
Disp Ans
getKey
prgmS
  • Entrez: 105,
  • Touche gauche: 24,
  • Touche droite: 26,
  • Ins [ert] est un peu différent car il faudrait normalement deux pressions sur les touches pour y accéder, mais celles-ci seraient 21 suivies de 23.

Voici une illustration du reste des touches:

entrez la description de l'image ici

Explication:

PROGRAMME: S L'éditeur affiche le nom en haut en dehors du code; le nom est "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

Malheureusement, cela n'est pas possible dans Arnold C, j'ai donc dû m'en tenir à TI-BASIC.

bearacuda13
la source
1
Cela fonctionne-t-il pour chaque clé de cette image? Sinon, pour quelles clés échoue-t-il?
2
Oui, cela fonctionne pour chaque touche sauf le bouton on, réservé pour tuer le programme sans sortir une batterie de la calculatrice.
bearacuda13
@ bearacuda13: J'ai une calculatrice égale que j'ai achetée il y a 18 ans et je ne connaissais pas le détail de la touche ON depuis des années. Je l'utilisais depuis la fin de l'université (il y a 11 ans), mais qui sait ...
sergiol
1

C #, 144 + 601 = 745 octets

Se compose de deux classes, je n'ai pas réussi à les combiner avec succès en une seule classe.

Classe principale:

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

Classe de crochet:

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

Les sorties:

  • Languette: 137
  • Pause: 147
  • Entrer: 141
  • NumPad Enter: 142
  • Fenêtres de gauche: 220
  • Fenêtres droites: 221
  • Insérer: 174
  • Insertion du pavé numérique: 224
TheLethalCoder
la source
Je peux réduire un peu les octets en passant ||à d' |autres golfs similaires, mais mon cerveau a besoin de repos après avoir fait ça!
TheLethalCoder
Dans la classe Hook, je pense que cela public int v;public int c;public int f;pourrait être raccourci àpublic int v,c,f;
Points d'interrogation
@QuestionMarks Une bonne idée va jouer au golf quand je reviens à un ordinateur
TheLethalCoder
1

AutoHotkey , 26 octets

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

Impossible de tester (gagnant uniquement), mais l' Moption indique

M: Les frappes modifiées telles que Contrôle-A à Contrôle-Z sont reconnues et transcrites si elles correspondent à de vrais caractères ASCII.

Donc ça devrait bien marcher.

phil294
la source
1

WinApi C ( gcc ), 156 octets

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

Ce programme imprime le code de clé virtuelle Windows associé à chaque touche d'entrée du clavier. Le \ndans le printfformat chaîne est facultative (mais rend la sortie de l' environnement humain) et peut être abandonné pour un score total de 154 octets . Un moyen facile de tuer le programme (sans taskmgr) est avec CTRL + PAUSE. Si vous avez un clavier avec une touche Fn, ce programme ne peut pas le récupérer car il n'est même pas remarqué par Windows.

  • Mention à la réponse de MooseBoys pour l' #include <d3d.h>astuce et l'inspiration pour le BYTEtableau.

Le programme avec des variables locales, la lisibilité et sans avertissements du compilateur ressemble à ceci:

#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
la source
1

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

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

Le code capture des clés même après la perte du focus.

Les captures d'écran suivantes sont enregistrées en ajoutant des espaces entre les sorties ( printf("%d ",j);+1 octet) pour une meilleure lisibilité:

capture d'écran clé

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

Le code utilise GetAsyncKeyStatepour interroger l'état des clés sans vérifier la file d'attente des messages, généralement plus en temps réel que les autres approches en mode utilisateur (sauf DirectInput). Cette approche est largement utilisée dans les enregistreurs de frappe.

(j<16||j>18)filtre régulièrement Ctrl / Alt / Maj. 16/17/18 est déclenché chaque fois que vous appuyez à gauche ou à droite, avec la valeur de la touche v spécifiée par l'emplacement.

Keyu Gan
la source
1

PowerShell, 34 octets

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

Sorties sur la même ligne que l'entrée, ce qui peut être un peu déroutant.

Gabriel Mills
la source