Qual tecla eu pressionei?

15

A tarefa é escrever um código para identificar qual tecla é pressionada no teclado. Você pode assumir que apenas uma tecla é pressionada por vez e que existe um layout de teclado padrão nos EUA. Esse é o layout com o @ sobre o 2.

Seu código deve gerar um identificador exclusivo para qualquer tecla pressionada. Isso inclui PrtScn, Scroll Lock, Pause, Shift esquerdo, Shift direito, Ctrl esquerdo, Ctrl direito, Caps Lock, Tab, Enter, Enter no teclado numérico, Num Lock, Inserir, Ins no teclado numérico, Backspace, Del, F1 ... F12, Esc, tecla esquerda do Windows, tecla direita do Windows, Alt, AltGr, tecla do aplicativo (menu de contexto) e assim por diante.

Seu código deve continuar aguardando pressionamentos de teclas e exibindo sua identidade até que seja eliminado. No entanto, ele deve gerar o identificador assim que uma chave for liberada. Ele não deve executar nenhuma outra ação das teclas pressionadas que recebe e não deve produzir nada além do identificador exclusivo.

Na sua resposta, mostre o que você codifica para as seguintes teclas pressionadas: Tab, Pausar, Enter, Enter no teclado numérico, tecla Windows esquerda, tecla Windows direita, Inserir e Ins no teclado numérico.

Se você possui um teclado muito diferente, o desafio ainda é gerar um identificador diferente para cada tecla do teclado.


fonte
1
No JS (JS do navegador, de qualquer maneira), é impossível verificar se certas teclas estão pressionadas (por exemplo, Caps Lock, Num Lock, Scroll Lock, PrtScn). Isso significa que o JS não pode responder?
ETHproductions
2
@ETHproductions Realmente. Desculpas aos amantes de JS em todos os lugares.
2
Requisitos modificados após o fornecimento de 5 respostas (incluindo uma agora excluída). Isso não é realmente justo ...
Olivier Grégoire -
6
Eu não acho que é justo / direita para a saída pedido de chaves que não são em muitos teclados, como o Windows chave etc.
Notts90 está fora de codidact.org
1
@ Notts90 Eles não fazem parte do layout de teclado padrão dos EUA? upload.wikimedia.org/wikipedia/commons/thumb/5/51/…

Respostas:

22

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

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Este é um executável COM para MS-DOS , requer um hardware compatível com IBM PC .
Particularmente um controlador 8042 PS / 2 ou, mais provavelmente, uma emulação dele através do SMM .
Para encurtar a história, deve funcionar imediatamente em qualquer PC convencional.

O código fonte é

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

Dividi o programa em duas partes.

A primeira parte trata da leitura dos scancodes . Scancodes são valores numéricos associados a cada chave.
Observe que estes são códigos de hardware, eles não dependem do sistema operacional ou do conjunto de caracteres. Eles são como um par codificado (coluna, linha) da chave.
Cada tecla possui um scancode, mesmo as teclas de função estranhas não padrão encontradas em algum teclado (por exemplo, a tecla "open calc").
Algumas chaves possuem scancode de vários bytes, possuem prefixos projetados para tornar o fluxo decodificável apenas olhando a sequência de bytes.
Assim, cada chave recebe seu identificador exclusivo, até CTRL, SHIFT, WinKeys e assim por diante.

Somente os "códigos de interrupção", enviados quando uma tecla é liberada, são processados, os "códigos de criação" são ignorados.
Os formadores têm o bit mais alto (bit 7 para um byte) definido, por isso é fácil reconhecê-los.

A segunda parte trata da impressão de um byte.
A impressão é sempre demorada na montagem, não temos componentes internos.
Para mantê-lo breve, e como era necessário escrever um identificador da chave, abandonei números decimais ou hexadecimais em favor de uma codificação pessoal.

Um byte xy, em que x é a mordidela mais alta e y, a mais baixa é impresso como dois caracteres sucessivos c 0 ec 1 definidos como:

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

Observe que a mordidela inferior é impressa primeiro (isso me poupou uma troca).
A lógica é mapear cada um dos 16 valores possíveis de uma mordidela em caracteres ASCII consecutivos de '!'.
Basta colocar este numeral hexadecimal, mas com

  1. Os petiscos trocados
  2. !"#$%&'()*+,-./01 como dígito (als) em vez de 0123456789abcdef

Executá-lo no DOSBox e pressionar alguma tecla aleatória (parte da qual é uma tecla especial, mas observe que, como um processo do Windows, o DOSBox não pode capturar todas as chaves) produz

DOSBox executando o identificador de chave

Observe que este programa nunca termina (além disso, ele assume o controle completo do PC desativando as interrupções), como eu acredito que foi pretendido pela pergunta (simplesmente não há eliminação de processos no DOS).


* Agradecimento reduzido a CodyGray .

Margaret Bloom
fonte
O uso da INinstrução foi menor em termos de bytes do que a interrupção da ROM BIOS (por exemplo int 16h, função 10h)?
Cody Gray
@CodyGray Provavelmente não, todo o loop pode ser pulado. De alguma forma, eu pulei direto para a ininstrução. Na verdade, esse é um ponto muito bom. Se você ainda não o fez, por que não publicá-lo como resposta? :)
Margaret Bloom
1
Bem, agora você está falando louco! Parece muito mais trabalho do que apenas comentar sua resposta existente. :-p Estou brincando de montar algo. No entanto, uma dica divertida: quando você joga golfe no código, xchgo acumulador como um dos registros tem 1 byte, melhor do que um byte de 2 bytes mov.
Cody Grey
1
Ok, o problema int 16hé que não recebo códigos de verificação para as teclas shift, bloqueio de rolagem ou pausa / pausa (talvez outras), e isso é exigido pelo desafio. Sua solução de ler a entrada diretamente da E / S funciona, embora pareça para mim que ela retorne o mesmo valor para todas as chaves no cluster Ins / Del / Home / End / PgUp / PgDown.
Cody Gray
1
@ PeterCordes: também PAUSE tem algum comportamento estranho, o IIUC enviando o código de interrupção juntamente com o código make ao pressionar a tecla, e não enviando nada na liberação da tecla. Ou foi o que entendi na Enciclopédia de Programação de Jogos para PC.
Njalj
12

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

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 graças a @ OlivierGrégoire para show(), 0<0eimport java.awt.event.*;

O que resulta em:

insira a descrição da imagem aqui

Até lida com pressionamentos de tecla para caracteres maiúsculos, tecla do Windows, trava de tampa, etc. Você pode vê-lo também imprimindo os 'modificadores', que são 'teclas retidas'.

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 polvo mágico
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Dennis
11

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

Usando isso para diferenciar a entrada e o retorno do numpad, LControl e RControl ... Não mais desde que os apsillers encontraram uma maneira de fazer isso com uma chamada de função de sinalização.

<body onkeyup=alert(event.code)

Saídas específicas:

SAÍDAS QUE AINDA ESTÃO COM OS NÚMEROS SÃO AQUELES QUE NÃO POSSO TESTAR NO MEU PORTÁTIL
POR FAVOR, AGUARDE-ME PARA ACESSAR ESSAS CHAVES

PrtScn -> PrintScreen
Lock Lock -> ScrollLock
Pause -> Pausar à
esquerda Shift -> ShiftLeft à
direita Shift -> ShiftRight à
esquerda Ctrl -> ContrlLeft à
direita Ctrl -> ControlRight
Caps Lock -> ControlRight Caps Lock ->
guia CapsLock -> guia
Enter -> Enter
Digite o número pad -> NumpadEntrar
Num Lock ->
Inserir NumLock -> Inserir
Ins no teclado numérico -> Numpad0
Backspace -> Backspace
Del -> Excluir
F1 ... F12 -> F1 a F12
Esc -> Escapar
tecla esquerda do Windows -> MetaLeft
direita Tecla do Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (tipo de buggy, ele detecta ControlLeft e depois AltRight,mas na verdade é AltRight)
chave do aplicativo (menu de contexto) -> ContextMenu

EDITs:
1 byte salvo ;após a chamada da função
18 bytes salvos graças aos Lil 'Bits e ETHproductions, eles notaram que eu esqueci de diminuir os nomes de func e var.
32 bytes salvos graças ao RogerSpielker, ele percebeu que eu estava fazendo código poupado sem motivo; e novamente -2 bytes: onkeydown-> onkeyup
1 byte salvo: sem necessidade de barra final
2 bytes salvos graças ao CraigAyre: with()função
2 bytes salvos graças ao ASCII-only: keyno lugar de which
4 bytes salvos, já que temos texto, não há necessidade para '-'+(todo identificador é único sem isso) 1 byte salvo graças ao ASCII-only (novamente): não há mais símbolo de fechamento > 15 bytes salvos graças aos apsillers, como dito na parte superior da minha resposta.

<body onkeyup=alert(event.code)

V. Courtois
fonte
Espere ... como é ... Caps Lock ... detectado? Eu pensei que era impossível ... Ah, tudo bem. PrtScn e SysRq não funcionam para mim, mas estou em um laptop com um pequeno teclado que usa Fn + End e Fn + Home para essas duas teclas.
ETHproductions
Eu gosto desta resposta, mas parece ter alguns problemas. O Tab não relata nada para mim quando o testo em codepen.io/anon/pen/MoLPQM . Além disso, F12, PrtScn não segue esta regra "Ele não deve executar nenhuma outra ação das teclas pressionadas que recebe e não deve produzir nada além do identificador exclusivo".
@Lembik usando html, não é realmente possível impedir que o sistema use a chave. Você precisa forçá-lo a não reconhecer as entradas principais com uma linguagem eficaz da máquina (ou sistema) (como C, talvez). E para guia, eu não sei que condições para trabalhar (quero dizer, ele funciona às vezes e às vezes não, eu não sei como minha resposta trata chaves traversable.
V. Courtois
@Lembik Se você visualizar o código em uma página autônoma (não um trecho ou rabeca ou similar), página em tela cheia (por exemplo, com F11), ele captura Guias; o fato de não capturar guias é uma função do estado do ambiente maior do navegador, não do código que está sendo executado na página. Como para prevenir comportamentos padrão, <body onkeydown=return!!alert(event.code)>deve fazer o truque, retornando falseemkeydown
apsillers
8

Tcl / Tk, 22 caracteres

bind . <Key> {puts %K}

Exemplo de execução:

chaves identificadas por Tcl / Tk

Notas:

  • Nenhuma tecla direita do Windows no meu teclado ☹ ( um designer inteligente colocou o interruptor da luz de fundo em seu lugar)
  • A inserção do teclado numérico gera código diferente com base no status do NumLock
  • O botão de volume gera códigos específicos do X.org, todos os outros são apenas academias de teclas regulares
homem a trabalhar
fonte
6

Bash com X.org, 21 bytes

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

Infelizmente, não posso testá-lo, pois estou no MacBook no Linux - sem PrntScr, sem teclado numérico e tudo.

xevé uma ferramenta que gera eventos de mouse e teclado em X.org. Eu o canalizo para awk, filtre as linhas pares (já que todas as teclas são mostradas quando a tecla é pressionada e, depois, liberada) e seleciono apenas as que contêm (k- essa string está em todas as linhas que descrevem a tecla pressionada.

enedil
fonte
Você poderia adicionar as saídas de exemplo listadas na pergunta, por favor.
1
@Lembik toda a saída aparece depois de sair.
18717 enedil
Ah Não é isso que a especificação pede. Vou esclarecer isso agora.
Isso gera um erro de sintaxe agora.
3
Observe que o Linux não implica X11. por exemplo, isso não funcionaria em um console de texto (use showkey -slá: P) ou em uma área de trabalho pura da Wayland GUI. Esta é realmente uma resposta bash + Xorg.
Peter Cordes
5

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

Saídas

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

Explicação

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

Editar% s

-16 graças a @ugoren

-8: alterado WNDCLASSpara intarray, pois todos os 10 membros têm 4 bytes

-11: inicialização parcial da matriz wndclass-data, reduzida para 9 elementos

-3: use intdeclínio implícito para a matriz wndclass-data

-8: remove a nova linha do formato de saída (não é necessário nas especificações e nos printf liberados imediatamente sem ela); mover RegisterClasspara CreateWindowarg, usando retornado ATOM; defina o nome wndclass comom qual apenas precisa de um byte zero para ser uma sequência válida.

-3: reutilizar wvar para MSGdados

MooseBoys
fonte
Fazer o mesmo com C ++ usando cout não seria muito mais curto?
Onrcanbektas
@Leth No. <iostream>+ std::cout<<a^b<<"\n"é mais longo. Além disso, acho que você precisaria adicionar tipos de retorno aos decls da função e mnão poderia estar implícito int.
MooseBoys
Salve um caractere comfor(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
ugoren
Além disso, p(x,y,a,b)e (void*)pdeve salvar alguns.
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);}}

Isso não pode ser executado com o TIO porque ele usa uma interface gráfica, mas funciona no meu computador.

Pausa: 153
Entrar: 81
Entre no NumPad: 84
Tecla Super esquerda: 193 (Depois de desativar o atalho de menu na área de trabalho)
Tecla super direita: 201
Inserção: 241
Inserir no Numpad: 522948 (eu não tenho um, mas é isso que você obtém ao pressionar 5 com o Num lock desativado. Quando o Num lock está ativado, você obtém 812.)

Ungolfed / Explicação:

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
fonte
Não parece que funciona para a tecla tab?
puxão
setFocusTraversalKeysEnabled(false);na sua resposta irá corrigir isso.
Magic Octopus Urn
@MagicOctopusUrn Eu não sei o que isso faz e acho que não quero: P
musicman523
Faz com que sua resposta funcione para a tecla TAB, pois sua resposta é inválida sem ela.
Magic Octopus Urn
Ohhhhh eu vejo - Tab é uma "tecla de foco"
musicman523
3

Scala 2.10+, 279 caracteres, 279 bytes

Agora, essa é uma resposta do scala :) mesmo que pareça que estou fazendo Java. De qualquer forma, não podemos testá-lo no 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){}})}}

É triste precisarmos declarar todos os métodos herdados, mesmo que não os utilizemos: Posso removê-los da contagem de bytes, pois alguns sinalizadores do compilador podem permitir não declará-los?

Isso imprime (como na minha resposta html-js) o keyPressed, "-" e, em seguida, seu "local".

Por exemplo :

PrtScn -> bloqueio de
rolagem não verificável -> 145-1
Pausa -> 19-1
Shift esquerdo -> 16-2
Shift direito -> 16-3
Ctrl esquerdo -> 17-2
Ctrl direito -> 17-3
Caps Lock -> 20-1
Guia -> não verificável
Digite -> 10-1
Digite no teclado numérico -> 10-4
Num Lock -> 144-4
Insira -> 96-1
Ins no teclado numérico -> 96-4
Backspace -> 8-1
Del -> 127-1
F1 ... F12 -> 112-1 a 123-1
Esc -> 27-1
tecla esquerda do Windows -> 524-2
tecla direita do Windows -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (tipo de buggy, ele detecta 17-2 e depois 18-3,mas é de fato 18-3)
chave do aplicativo (menu de contexto) -> 525-1

Embora eu pense que depende do computador: / Eu estou em um laptop azerty agora.

V. Courtois
fonte
Se você não quiser contar as declarações desnecessárias, pode ser necessário incluir o comprimento dos sinalizadores do compilador não padrão. A menos que os compiladores antigos usem como padrão isso? As respostas C geralmente precisam ser compiladas, -std=c89já que os compiladores modernos assumem o padrão c99 ou c11, mas não precisam contar isso. Portanto, não tenho certeza de qual seria a decisão da meta de código-golfe.
Peter Cordes
3

TI-BASIC, 19 bytes

PROGRAMA: S

If Ans
Disp Ans
getKey
prgmS
  • Digite: 105,
  • Tecla esquerda: 24,
  • Tecla direita: 26,
  • Ins [ert] é um pouco diferente porque normalmente seriam necessárias duas teclas para chegar, mas essas seriam 21 seguidas de 23.

Aqui está uma ilustração do restante das chaves:

insira a descrição da imagem aqui

Explicação:

PROGRAMA: S O editor exibe o nome na parte superior do código; o nome é "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

Infelizmente, isso não é possível em Arnold C, então tive que me ater ao TI-BASIC.

bearacuda13
fonte
1
Funciona para todas as chaves nessa imagem? Se não, de quais chaves ele falha?
2
Sim, ele funciona para todas as teclas, exceto o botão ligar, reservado para matar o programa sem tirar a bateria da calculadora.
bearacuda13
@ bearacuda13: Eu tenho uma calculadora igual que comprei há 18 anos e não conhecia os detalhes da chave ON por anos. Eu estava usando-o desde o final da universidade (11 anos atrás), mas quem sabe ...
sergiol 24/10
1

C #, 144 + 601 = 745 bytes

Consiste em duas classes, não consegui combiná-las com êxito em uma classe.

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

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

Saídas:

  • Aba: 137
  • Pausa: 147
  • Entrar: 141
  • NumPad Enter: 142
  • Janelas Esquerdas: 220
  • Windows direito: 221
  • Inserir: 174
  • Inserção NumPad: 224
TheLethalCoder
fonte
Posso diminuir um pouco os bytes mudando ||para |outros golfes semelhantes, mas meu cérebro precisa descansar depois de fazer isso!
TheLethalCoder
Na classe Hook, acho que public int v;public int c;public int f;poderia ser encurtado parapublic int v,c,f;
Pontos de interrogação
@QuestionMarks Boa ideia de golfe vontade quando eu voltar a um computador
TheLethalCoder
1

AutoHotkey , 26 bytes

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

Não é possível testar (somente vitória), mas a Mopção diz

M: As teclas modificadas, como Control-A a Control-Z, são reconhecidas e transcritas se corresponderem a caracteres ASCII reais.

Portanto, deve dar certo.

phil294
fonte
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 o código de chave virtual do Windows associado a cada tecla do teclado de entrada. O \nno printfformato de string é opcional (mas torna saída amigável humano) e pode ser caiu para uma pontuação total de 154 bytes . Uma maneira fácil de matar o programa (sem taskmgr) é com CTRL + PAUSE. Se você possui um teclado com uma tecla Fn, este programa não pode ser capturado, pois nem é percebido pelo Windows.

  • Agradecemos a resposta da MooseBoys pelo #include <d3d.h>truque e inspiração para a BYTEmatriz.

O programa com variáveis ​​locais, legibilidade e sem avisos do compilador tem a seguinte aparência:

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

O código captura chaves mesmo depois que o foco é perdido.

As seguintes capturas de tela são registradas adicionando espaços entre as saídas ( printf("%d ",j);+1 byte) para melhor legibilidade:

key 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

O código usa GetAsyncKeyStatepara consultar o estado da chave sem verificar a fila de mensagens, geralmente mais em tempo real do que outras abordagens no modo de usuário (exceto DirectInput). Essa abordagem é amplamente usada em keyloggers.

(j<16||j>18)filtra Ctrl / Alt / Shift regulares. 16/17/18 é acionado sempre que o botão esquerdo ou direito é pressionado, juntamente com o valor de vkey especificado pelo local.

Keyu Gan
fonte
1

PowerShell, 34 bytes

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

Saídas na mesma linha da entrada, o que pode ser um pouco confuso.

Gabriel Mills
fonte