¿Qué tecla presioné?

15

La tarea es escribir código para identificar qué tecla se presiona en el teclado. Puede suponer que solo se presiona una tecla a la vez y que hay un diseño de teclado estándar de EE. UU. Ese es el diseño con la @ sobre el 2.

Su código debe generar un identificador único para cualquier tecla presionada. Esto incluye PrtScn, Scroll Lock, Pause, left Shift, right Shift, left Ctrl, right Ctrl, Caps Lock, Tab, Enter, Enter en el teclado numérico, Bloq Num, Insertar, Ins en el teclado numérico, Retroceso, Supr, F1 ... F12, Esc, tecla izquierda de Windows, tecla derecha de Windows, Alt, AltGr, tecla de aplicación (menú contextual), etc.

Su código debe continuar esperando que se presionen las teclas y generando su identidad hasta que se elimine. Sin embargo, debe generar el identificador tan pronto como se suelte una clave. No debe realizar ninguna otra acción de las pulsaciones de teclas que recibe y no debe generar nada aparte del identificador único.

En su respuesta, muestre lo que codifica para las siguientes pulsaciones de teclas: Tabulador, Pausa, Intro, Intro en el teclado numérico, tecla izquierda de Windows, tecla derecha de Windows, Insertar e Ins en el teclado numérico.

Si tiene un teclado muy diferente, el desafío sigue siendo generar un identificador diferente para cada tecla de su teclado.


fuente
1
En JS (navegador JS, de todos modos), es imposible verificar si se presionan ciertas teclas (por ejemplo, Bloq Mayús, Bloq Num, Bloqueo de desplazamiento, PrtScn). ¿Esto significa que JS no puede responder?
ETHproductions
2
@ETHproductions De hecho lo hace. Disculpas a los amantes de JS en todas partes.
2
Se modifican los requisitos después de proporcionar 5 respuestas (incluida una ahora eliminada). Eso no es realmente justo ...
Olivier Grégoire
66
No creo que sea justo / derecha a la salida de solicitud de claves que no están en muchos teclados como tecla de Windows, etc.
Notts90 ha tenido codidact.org
1
@ Notts90 ¿No son parte de la distribución estándar del teclado de EE. UU.? upload.wikimedia.org/wikipedia/commons/thumb/5/51/…

Respuestas:

22

código de máquina x86, ejecutable de DOS, 29 * 28 bytes

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Este es un ejecutable COM para MS-DOS , requiere un hardware compatible con PC de IBM .
Particularmente un controlador 8042 PS / 2 o más probablemente una emulación del mismo través de SMM .
En pocas palabras, debería funcionar de forma inmediata en cualquier PC convencional.

El código fuente es

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

He dividido el programa en dos partes.

La primera parte trata de la lectura de los códigos de escaneo . Los códigos de escaneo son valores numéricos asociados con cada clave.
Tenga en cuenta que estos son códigos de hardware, no dependen del sistema operativo o del juego de caracteres. Son como un par codificado (columna, fila) de la clave.
Cada tecla tiene un código de escaneo, incluso aquellas teclas de función extrañas no estándar que se encuentran en algún teclado (por ejemplo, la tecla "abrir cálculo").
Algunas claves tienen un código de escaneo de varios bytes, tienen prefijos diseñados para hacer que la secuencia sea decodificable con solo mirar la secuencia de bytes.
Por lo tanto, cada tecla obtiene su identificador único, incluso CTRL, SHIFT, WinKeys, etc.

Solo se procesan los "códigos de interrupción", enviados cuando se suelta una tecla, se ignoran los "códigos de creación".
Los formadores tienen el conjunto de bits más alto (bit 7 para un byte), por lo que es fácil reconocerlos.

La segunda parte trata de la impresión de un byte.
La impresión siempre es larga en el ensamblaje, no tenemos incorporados.
Para que sea breve, y dado que era necesario escribir un identificador de la clave, abandoné los números decimales o hexadecimales a favor de una codificación personal.

Un byte xy, donde x es el mordisco más alto y y el más bajo se imprime como dos caracteres sucesivos c 0 y c 1 definidos como:

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

Tenga en cuenta que el mordisco inferior se imprime primero (esto me ahorró un intercambio).
La razón es mapear cada uno de los 16 valores posibles de un mordisco en caracteres ASCII consecutivos de '!'.
En pocas palabras, este es un número hexadecimal pero con

  1. Los mordiscos intercambiados
  2. !"#$%&'()*+,-./01 como dígito (als) en lugar de 0123456789abcdef

Ejecutarlo en DOSBox y presionar alguna tecla aleatoria (parte de la cual es una tecla especial, pero tenga en cuenta que, como proceso de Windows, DOSBox no puede capturar todas las teclas) produce

DOSBox ejecutando el identificador de clave

Tenga en cuenta que este programa nunca termina (además, toma el control completo de la PC al deshabilitar las interrupciones) como creo que fue la intención (simplemente no hay eliminación de procesos en DOS).


* Reducido gracias a CodyGray .

Margaret Bloom
fuente
¿El uso de la INinstrucción resultó ser más pequeño en términos de bytes que llamar a las interrupciones del BIOS ROM (por ejemplo int 16h, la función 10h)?
Cody Gray
@CodyGray Lo más probable es que no se pueda omitir todo el bucle. De alguna manera, salté directamente a las ininstrucciones. Ese es realmente un muy buen punto que tienes. Si aún no lo ha hecho, ¿por qué no publicarlo como respuesta? :)
Margaret Bloom
1
Bueno, ahora estás hablando loco! Eso suena como mucho más trabajo que solo comentar su respuesta existente. :-p Estoy jugando con armar algo. Sin embargo, un consejo divertido: cuando el golf de código, xchgcon el acumulador como uno de los registros es de 1 byte, es mejor que un byte de 2 mov.
Cody Gray
1
De acuerdo, el problema int 16hes que no obtengo códigos de escaneo para las teclas de mayúsculas, bloqueo de desplazamiento o pausa / pausa (tal vez otros), y eso es requerido por el desafío. Su solución de leer la entrada directamente desde la E / S funciona, aunque me parece que devuelve el mismo valor para todas las teclas en el clúster Ins / Del / Home / End / PgUp / PgDown.
Cody Gray
1
@PeterCordes: también PAUSE tiene un comportamiento extraño, IIUC envía el código de interrupción junto con el código make al presionar la tecla, y no envía nada al soltar la tecla. O eso es lo que entendí de la Enciclopedia de programación de juegos de PC.
ninjalj
12

Java 7 o superior, 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);}};}}

Sin 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 gracias a @ OlivierGrégoire por show(),0<0 yimport java.awt.event.*;

Lo que resulta en:

ingrese la descripción de la imagen aquí

Incluso maneja las pulsaciones de mayúsculas para los caracteres en mayúscula, la tecla de Windows, los bloqueos de mayúsculas, etc. También puede verlo imprimiendo los 'modificadores', que son 'teclas retenidas'.

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 de pulpo mágico
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Dennis
11

HTML (con Javascript), 46 31 caracteres, 46 31 bytes

Utilizando esto para diferenciar el teclado numérico enter y return, LControl y RControl ... Ya no, ya que los apsillers encontraron una manera de hacerlo con una llamada de función de señal.

<body onkeyup=alert(event.code)

Salidas específicas:

LOS PRODUCTOS QUE TODAVÍA ESTÁN CON LOS NÚMEROS SON LOS QUE NO PUEDO PROBAR EN MI COMPUTADORA PORTÁTIL
POR FAVOR ESPERE QUE TENGO ACCESO A ESAS TECLAS

PrtScn -> PrintScreen
Scroll Lock -> ScrollLock
Pause -> Pause
left Shift -> ShiftLeft
right Shift -> ShiftRight
left Ctrl -> ContrlLeft
right Ctrl -> ControlRight
Caps Lock -> TabLock
Tab -> Tab
Enter -> Enter
Enter en el número pad -> Numpad Ingrese
Num Lock -> NumLock
Insert -> Insert
Ins en el teclado numérico -> Numpad0
Retroceso -> Retroceso
Supr -> Eliminar
F1 ... F12 -> F1 a F12
Esc -> Escape
izquierda Tecla de Windows -> MetaLeft
derecha Tecla de Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (tipo de error, detecta ControlLeft y luego AltRight,pero de hecho es AltRight)
aplicación (menú contextual) -> ContextMenu

EDITOS:
1 byte guardado ;después de la llamada de func
18 bytes guardados gracias a Lil 'Bits y ETHproductions, notaron que olvidé acortar los nombres de func y var.
32 bytes guardados gracias a RogerSpielker, notó que estaba haciendo código espaciado sin ninguna razón; y nuevamente -2 bytes: onkeydown-> onkeyup
1 byte guardado: no es necesario para la barra final
2 bytes guardados gracias a CraigAyre: with()función
2 bytes guardados gracias a ASCII-only: keyen lugar de which
4 bytes guardados, ya que tenemos texto, no hay necesidad for '-'+(cada identificador es único sin esto) 1 byte guardado gracias a ASCII-only (nuevamente): no más símbolo de cierre > 15 bytes guardados gracias a apsillers, como se dice en la parte superior de mi respuesta.

<body onkeyup=alert(event.code)

V. Courtois
fuente
Espera ... ¿cómo se detecta ... Bloq Mayús ... Pensé que era imposible ... Huh, bueno. PrtScn y SysRq no funcionan para mí, pero estoy en una computadora portátil con un pequeño teclado que usa Fn + End y Fn + Home para esas dos teclas.
ETHproductions
Me gusta esta respuesta pero parece tener algunos problemas. Tab no me informa nada cuando lo pruebo en codepen.io/anon/pen/MoLPQM . También F12, PrtScn no sigue esta regla "No debe realizar ninguna otra acción de las pulsaciones de teclas que recibe y no debe generar nada aparte del identificador único".
@Lembik usando html, realmente no es posible evitar que el sistema use la clave. Debe forzarlo a que no reconozca las entradas clave con un lenguaje efectivo de máquina (o sistema) (como C quizás). Y para tab, no sé en qué condiciones funciona (quiero decir, a veces funciona y a veces no, no sé cómo mi respuesta trata las claves transitables.
V. Courtois
@Lembik Si ve el código de forma independiente (no es un fragmento o violín o similar), página de pantalla completa (por ejemplo, con F11), captura pestañas; El hecho de que no capture pestañas es una función del estado del entorno del navegador más grande, no del código que se ejecuta en la página. En cuanto a la prevención de comportamientos predeterminados, <body onkeydown=return!!alert(event.code)>debería hacer el truco volviendofalse sobrekeydown
apsillers
8

Tcl / Tk, 22 caracteres

bind . <Key> {puts %K}

Ejecución de muestra:

claves identificadas por Tcl / Tk

Notas:

  • No tengo la tecla de Windows correcta en mi teclado ☹ (el diseñador inteligente puso el interruptor de luz de fondo en su lugar)
  • La inserción del teclado numérico genera un código diferente en función del estado de NumLock
  • La perilla de volumen genera códigos específicos de X.org, todos los demás son solo keyyms regulares
hombre trabajando
fuente
6

Bash con X.org, 21 bytes

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

Desafortunadamente, no puedo probarlo ya que estoy en MacBook en Linux: sin PrntScr, sin teclado numérico y todo.

xeves una herramienta que genera eventos de mouse y teclado en X.org. Lo canalizo a awk, filtro líneas pares (ya que cada tecla se muestra cuando se presiona la tecla, y luego cuando se suelta), y selecciono solo las que contienen (k: esta cadena se encuentra en cada línea que describe la tecla presionada.

enedil
fuente
¿Podría agregar los resultados de ejemplo enumerados en la pregunta, por favor?
1
@Lembik toda la salida aparece después de salir.
enedil
Ah Eso no es lo que pide la especificación. Lo aclararé ahora.
Esto da un error de sintaxis ahora.
3
Tenga en cuenta que Linux no implica X11. por ejemplo, esto no funcionaría en una consola de texto (use showkey -sallí: P), o en un escritorio de GUI de Wayland puro. Esta es realmente una respuesta bash + Xorg.
Peter Cordes
5

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

Salidas

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

Explicación

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

Ediciones

-16 gracias a @ugoren

-8: cambiado WNDCLASSa intmatriz ya que los 10 miembros son 4 bytes

-11: inicialización parcial de la matriz de datos wndclass, reducida a 9 elementos

-3: utiliza intdeclinación implícita para la matriz de datos wndclass

-8: eliminar la nueva línea del formato de salida (no se requiere en la especificación y printf se vacía inmediatamente sin ella); pasar RegisterClassa CreateWindowarg, usando return ATOM; establecer wndclass name enm que solo necesita un byte cero para que sea una cadena válida.

-3: reutilizar wvar para MSGdatos

MooseBoys
fuente
¿Hacer lo mismo con C ++ usando cout no sería mucho más corto?
onurcanbektas
@Leth No. <iostream>+ std::cout<<a^b<<"\n"es más largo. Además, creo que necesitaría agregar tipos de retorno a la función decls, y mno podría ser implícito int.
MooseBoys
Ahorre un char confor(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
ugoren
Además, p(x,y,a,b)y (void*)pdebería guardar algunos.
ugoren
3

Java (OpenJDK 8) , 369 bytes

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

Esto no se puede ejecutar con TIO porque usa una interfaz gráfica, pero funciona en mi computadora.

Pausa: 153
Entrar: 81
Ingrese en NumPad: 84
Tecla súper izquierda: 193 (después de deshabilitar el acceso directo del menú para mi escritorio)
Súper tecla derecha: 201
Insertar: 241
Insertar en el teclado numérico: 522948 (no tengo uno, pero eso es lo que obtienes cuando presionas 5 con el bloqueo numérico desactivado. Cuando el bloqueo numérico está activado, obtienes 812).

Sin golf / Explicación:

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
fuente
¿No parece que funciona para la tecla de tabulación?
Poke
setFocusTraversalKeysEnabled(false);en su respuesta arreglará esto.
Magic Octopus Urn
@MagicOctopusUrn No sé lo que hace y no creo que quiera: P
musicman523
Hace que su respuesta funcione para la tecla TAB, ya que su respuesta no es válida sin ella.
Magic Octopus Urn
Ohhhhh ya veo - Tab es una "clave de enfoque transversal"
musicman523
3

Scala 2.10+, 279 caracteres, 279 bytes

Ahora, esta es una respuesta de escala :) aunque parece que estoy haciendo Java. De todos modos, no podemos probarlo en 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){}})}}

Es triste que necesitemos declarar todos los métodos heredados incluso si no los usamos: ¿Puedo eliminarlos del recuento de bytes, ya que algunos indicadores del compilador pueden permitir no declararlos?

Esto imprime (en cuanto a mi respuesta html-js) la tecla presionada, "-" y luego su "ubicación".

Por ejemplo :

PrtScn -> Bloqueo de
desplazamiento no verificable -> 145-1
Pausa -> 19-1
izquierda Shift -> 16-2
derecha Shift -> 16-3
izquierda Ctrl -> 17-2
derecha Ctrl -> 17-3
Bloq Mayús -> 20-1
Pestaña -> no verificable
Ingresar -> 10-1
Ingresar en el teclado numérico -> 10-4
Bloqueo numérico -> 144-4
Insertar -> 96-1
Ins en el teclado numérico -> 96-4
Retroceso -> 8-1
Supr -> 127-1
F1 ... F12 -> 112-1 a 123-1
Esc -> 27-1
tecla de Windows izquierda -> 524-2
tecla de Windows derecha -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (tipo de buggy, detecta 17-2 y luego 18-3,pero de hecho es 18-3)
clave de aplicación (menú contextual) -> 525-1

Aunque creo que depende de la computadora: / Estoy en una computadora portátil azerty en este momento.

V. Courtois
fuente
Si no desea contar las declaraciones innecesarias, es posible que deba incluir la longitud de los indicadores del compilador no estándar. ¿A menos que los compiladores antiguos solían usar eso por defecto? Las respuestas C generalmente deben compilarse -std=c89ya que los compiladores modernos tienen por defecto el valor c99 o c11, pero no necesitan contar eso. Por lo tanto, no estoy seguro de cuál sería el fallo del código golf meta.
Peter Cordes
3

TI-BASIC, 19 bytes

PROGRAMA: S

If Ans
Disp Ans
getKey
prgmS
  • Ingrese: 105,
  • Tecla izquierda: 24,
  • Clave derecha: 26,
  • Ins [ert] es un poco diferente porque normalmente se necesitarían dos pulsaciones de teclas para llegar, pero serían 21 seguidas de 23.

Aquí hay una ilustración del resto de las teclas:

ingrese la descripción de la imagen aquí

Explicación:

PROGRAMA: S El editor muestra el nombre en la parte superior aparte del código; el nombre es "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

Esto, desafortunadamente, no es posible en Arnold C, así que tuve que apegarme a TI-BASIC.

bearacuda13
fuente
1
¿Funciona para cada clave en esa imagen? Si no, ¿para qué teclas falla?
2
Sí, funciona para cada tecla, excepto el botón de encendido, reservado para matar el programa sin sacar una batería de la calculadora.
bearacuda13
@ bearacuda13: Tengo una calculadora igual que compré hace 18 años y no conocía los detalles de la tecla ON durante años. Lo había estado usando desde el final de la universidad (hace 11 años), pero quién sabe ...
#
1

C #, 144 + 601 = 745 bytes

Consiste en dos clases, no pude combinarlas con éxito en una sola clase.

Clase principal:

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

Clase de gancho:

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

Salidas:

  • Lengüeta: 137
  • Pausa: 147
  • Entrar: 141
  • NumPad Enter: 142
  • Ventanas izquierdas: 220
  • Windows derecho: 221
  • Insertar: 174
  • NumPad Insert: 224
TheLethalCoder
fuente
Puedo bajar un poco los bytes cambiando ||a |y otros campos de golf similares, ¡pero mi cerebro necesita descansar después de hacer eso!
TheLethalCoder
En la clase Hook, creo que public int v;public int c;public int f;podría acortarse apublic int v,c,f;
Signos de interrogación
@QuestionMarks Buena idea jugará golf cuando vuelva a una computadora
TheLethalCoder
1

AutoHotkey , 26 bytes

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

No se puede probar (solo ganar), pero la Mopción dice

M: las pulsaciones de teclas modificadas, como Control-A a Control-Z, se reconocen y transcriben si corresponden a caracteres ASCII reales.

Entonces debería hacerlo bien.

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

Este programa imprime el código de clave virtual de Windows asignado con cada tecla de entrada de teclado. El \nen la printfcadena de formato es opcional (pero hace que la salida sea amigable para los humanos) y puede descartarse para una puntuación total de 154 bytes . Una manera fácil de matar el programa (sin taskmgr) es con CTRL + PAUSE. Si tiene un teclado con una tecla Fn, este programa no puede recuperarlo, ya que Windows ni siquiera lo nota.

  • Gracias a la respuesta de MooseBoys por el #include <d3d.h>truco e inspiración para la BYTEmatriz.

El programa con variables locales, legibilidad y sin advertencias del compilador se ve así:

#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;
}
Señor al azar
fuente
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;}

El código captura claves incluso después de perder el foco.

Las siguientes capturas de pantalla se graban agregando espacios entre salidas ( printf("%d ",j);+1 byte) para una mejor lectura:

captura de pantalla clave

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

El código se usa GetAsyncKeyStatepara consultar el estado de la clave sin verificar la cola de mensajes, generalmente más en tiempo real que otros enfoques de modo de usuario (excepto DirectInput). Este enfoque es ampliamente utilizado en keyloggers.

(j<16||j>18)filtra Ctrl / Alt / Shift regular. 16/17/18 se activa cada vez que se presiona el botón izquierdo o derecho, junto con el valor de la tecla v especificado por la ubicación.

Keyu Gan
fuente
1

PowerShell, 34 bytes

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

Salidas en la misma línea que la entrada, lo que puede ser un poco confuso.

Gabriel Mills
fuente