Hangi tuşa bastım?


15

Görev, klavyede hangi tuşa basıldığını tanımlamak için kod yazmaktır. Bir seferde yalnızca bir tuşa basıldığını ve standart bir ABD klavye düzeni olduğunu varsayabilirsiniz. 2 üzerinde @ olan düzen budur.

Kodunuz, basılan herhangi bir tuş için benzersiz bir tanımlayıcı çıkarmalıdır. Bu, PrtScn, Kaydırma Kilidi, Duraklatma, sol Shift, sağ Shift, sol Ctrl, sağ Ctrl, Caps Lock, Sekme, Enter, Sayısal tuş takımındaki Enter, Num Lock, Ekle, sayısal tuş takımındaki ins, Geri tuşu, Del, F1 ... F12, Esc, sol Windows tuşu, sağ Windows tuşu, Alt, AltGr, uygulama tuşu (içerik menüsü) vb.

Kodunuz tuş basışlarını beklemeye ve kimliklerini öldürülünceye kadar çıktılarına devam etmelidir. Ancak, bir anahtar bırakıldığında tanıtıcıyı çıktılamalıdır. Aldığı tuş preslerinden başka bir işlem yapmamalı ve benzersiz tanımlayıcıdan başka bir şey çıkarmamalıdır.

Cevabınızda, lütfen aşağıdaki tuşa basıldığında çıktılarınızı kodladığınız şeyi gösterin: Sekme, Duraklatma, Enter, sayısal tuş takımında Enter, sol Windows tuşunda, sağ Windows tuşunda, sayısal tuş takımında Insert ve Ins.

Çok farklı bir klavyeniz varsa, meydan okuma yine de klavyenizdeki her tuş için farklı bir tanımlayıcı çıkarmaktır.


1
JS'de (yine de tarayıcı JS,), belirli tuşlara basıldığını kontrol etmek imkansızdır (örn. Caps Lock, Num Lock, Scroll Lock, PrtScn). Bu JS'nin cevaplayamayacağı anlamına mı geliyor?
ETHproductions

2
@ETHproductions Gerçekten de öyle. Her yerde JS sevenler için özür dileriz.

2
5 cevap verildikten sonra değiştirilen gereksinimler (şimdi silinenler dahil). Bu gerçekten adil değil ...
Olivier Grégoire

6
Windows tuşu
vb.Gibi

1
@ Notts90 Standart ABD klavye düzeninin parçası değiller mi? upload.wikimedia.org/wikipedia/commons/thumb/5/51/…

Yanıtlar:


22

x86 makine kodu, DOS çalıştırılabilir, 29 * 28 bayt

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Bu, MS-DOS için bir COM yürütülebilir dosyasıdır , IBM PC uyumlu bir donanım gerektirir .
Özellikle 8042 PS / 2 kontrolör veya SMM yoluyla daha fazla taklit edilmesi . Uzun lafın kısası, herhangi bir ana bilgisayarda kutunun dışında çalışmalıdır.

Kaynak kodu

BITS 16

 ;Disable the interrupts so we don't compete with the IRQ 1 (the 8042 main
 ;device IRQ) handler (the ISR n. 9 by default) for the reading of the codes.
 cli

_wait:

 ;Is 'Output buffer full (OBF)' bit set?

 in al, 64h                ;Read the 8042 status register             
 shr al, 1                 ;Move bit 0 (OBF) into the carry flag

jnc _wait                  ;Keep spinning if CF = OBF not set

 ;Read the scan code S
 in al, 60h

 ;Is S a break code?

 shl al, 1                 ;Bit 7 is set if it is
jnc _wait

 ;PART 2

 ;AL = S mod 10h := y, AH = S / 10h := x
 aam 16
 add ax, 2121h             ;Make both quantities in the printable ASCII range (skip space though)

 ;Print y
 xchg dx, ax
 mov ah, 02h
 int 21h                   ;int 21/ah=02 prints the char in DL

 ;DH is still valid here, it holds x. We print it now
 mov dl, dh
 int 21h

 ;Never terminate
jmp _wait

Programı iki bölüme ayırdım.

İlk bölüm, tarama kodlarının okunmasıyla ilgilidir . Tarama kodları, her tuşla ilişkilendirilmiş sayısal değerlerdir.
Bunların donanım kodu olduğunu, işletim sistemine veya karakter kümesine bağlı olmadığını unutmayın. Anahtarın kodlanmış bir çifti (sütun, satır) gibidirler.
Her tuşun bir tarama kodu vardır, hatta bazı klavyede bulunan standart olmayan garip işlev tuşları bile (örn. "Calc" tuşu).
Bazı anahtarlar çok baytlı tarama koduna sahiptir, sadece bayt sırasına bakarak akışı çözülebilir hale getirmek için tasarlanmış öneklere sahiptir.
Böylece her anahtarın benzersiz tanımlayıcısı, CTRL, SHIFT, WinKeys vb.

Yalnızca bir anahtar bırakıldığında gönderilen "kesme kodları" işlenir, "kod oluşturma" dikkate alınmaz.
Biçimlendiriciler daha yüksek bit (bayt için bit 7) kümesine sahiptir, bu yüzden onları tanımak kolaydır.

İkinci bölüm bir bayt baskısı ile ilgilidir.
Montajda baskı her zaman uzundur, yerleşikimiz yoktur.
Kısa tutmak için ve anahtarın bir tanımlayıcısını yazmam gerektiğinden, kişisel kodlama lehine ondalık veya onaltılık sayılardan vazgeçtim.

X daha yarım bayt ve y alt c birbirini takip eden iki karakter olarak basılır olan bir bayt xy, 0 ve c 1 aşağıdaki şekilde tanımlanmıştır:

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

Önce alt kemirin basıldığına dikkat edin (bu bana bir değişiklik verdi).
Gerekçe, bir kemirin 16 olası değerinin her birini '!' Karakterinden ardışık ASCII karakterlerine eşlemektir.
Basitçe söylemek gerekirse bu bir onaltılık sayıdır, ancak

  1. Nibbles takas edildi
  2. !"#$%&'()*+,-./01 yerine rakam (als) olarak 0123456789abcdef

DOSBox'ta çalıştırmak ve bazı rastgele tuşlara basmak (bazıları özel bir anahtardır, ancak bir Windows işlemi olarak DOSBox'ın tüm anahtarları yakalayamayacağını unutmayın)

DOSBox running the key identifier

Bu program asla sona erdiğini unutmayın (ayrıca, kesintileri devre dışı bırakarak PC'nin tam kontrolünü alır) soru tarafından tasarlandığını düşündüğüm gibi (sadece DOS'ta işlemlerin öldürülmesi yoktur).


* CodyGray'a teşekkür etti .


INTalimatı kullanmak, baytlar açısından ROM BIOS kesintilerini çağırmaktan daha küçük (örneğin int 16h, işlev 10h) işe yaradı mı?
Cody Gray

@CodyGray Büyük olasılıkla, tüm döngü atlanabilir. Her nasılsa doğrudan intalimatlara atladım . Bu aslında sahip olduğunuz çok iyi bir nokta. Henüz yapmadıysanız, neden cevap olarak göndermiyorsunuz? :)
Margaret Bloom

1
Şimdi çılgın konuşuyorsun! Bu sadece mevcut cevabınıza yorum yapmaktan çok daha fazla iş gibi geliyor. :-p Bir şeyleri bir araya getirmekle oynuyorum. Eğlenceli ipucu, ancak: kod golf yaparken xchg, akümülatör ile bir kayıt olarak 1 bayt, bu yüzden 2 bayt daha iyidir mov.
Cody Gray

1
Tamam, sorun int 16h, shift tuşları, kaydırma kilidi veya duraklat / kır (belki diğerleri) için tarama kodları alamıyorum ve bu meydan okuma tarafından gerekli olmasıdır. Girişi doğrudan G / Ç'den okuma çözümünüz çalışıyor, ancak bana benziyor olsa da Ins / Del / Home / End / PgUp / PgDown kümesindeki tüm tuşlar için aynı değeri döndürüyor.
Cody Gray

1
@PeterCordes: PAUSE'ın tuhaf bir davranışı var, IIUC, tuş kodunu make koduyla birlikte kesme kodunu gönderiyor ve tuşa basıldığında hiçbir şey göndermiyor. Ya da PC Oyun Programlama Ansiklopedisinden anladım.
ninjalj

12

Java 7 veya daha yüksek, 246 228 bayt

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 @ @ OlivierGrégoire sayesinde show(),0<0 veimport java.awt.event.*;

Sonuç:

enter image description here

Büyük harfli karakterler, windows tuşu, kapak kilitleri, vb.

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

Yorumlar uzun tartışmalar için değildir; bu görüşme sohbete taşındı .
Dennis

11

HTML (Javascript ile), 46 31 karakter, 46 31 bayt

Bu numpad enter ve return, LControl ve RControl farklılaştırmak için kullanarak ... Artık apsillers bir signle işlev çağrısı ile yapmak için bir yol buldum beri.

<body onkeyup=alert(event.code)

Özel çıktılar:

DİZÜSTÜ SAYILARLA HALA ÇIKAN ÇIKTILAR DİZÜSTÜ BİLGİSAYARIMDA TEST EDEMİYORUM
LÜTFEN LÜTFEN BU ANAHTARLARA ERİŞMEK İÇİN BEKLEYECEK

PrtScn -> PrintScreen
Kaydırma Kilidi -> ScrollLock
Duraklat ->
Sol Shift'i Duraklat -> ShiftLeft
sağ Shift -> ShiftRight
sol Ctrl -> ContrlLeft
sağ Ctrl -> ControlRight
Caps Kilidi -> CapsLock
Sekmesi -> Sekme
Enter -> Enter
Enter pad -> NumpadEnter
Num Lock -> NumLock
Ekle ->
Sayısal tuş takımında Ins ekle -> Numpad0
Backspace -> Backspace
Del -> Sil
F1 ... F12 -> F1 - F12
Esc ->
Soldan sol Windows tuşu -> MetaLeft
sağ Windows tuşu -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (buggy türü, ControlLeft'i ve ardından AltRight'ı algılar,ama gerçekten AltRight)
uygulama anahtarı (içerik menüsü) -> ContextMenu

EDITs: func çağrı sonra
1 bayt Lil 'Bit ve ETHproductions sayesinde kaydedilen 18 bayt kaydedildi, func ve var isimlerini kısaltmak unuttum fark ettiler. RogerSpielker sayesinde 32 bayt tasarruf etti, sebepsiz kodlama yaptığımı fark etti; ve tekrar -2 bayt: -> 1 bayt kaydedildi: son eğik çizgiye gerek yok CraigAyre sayesinde kaydedildi 2 bayt: sadece ASCII sayesinde fonksiyon 2 bayt: kaydedilen 4 bayt yerine, metnimiz olduğu için, gerek yok for (her tanımlayıcı bu olmadan benzersizdir) Sadece ASCII sayesinde 1 bayt kaydedildi (tekrar): cevabımın en üstünde söylendiği gibi, apsiller sayesinde 15 bayt kaydedilmiyor. ;

onkeydownonkeyup

with()
keywhich
'-'+>

<body onkeyup=alert(event.code)


Bekle ... nasıl ... Caps Lock ... tespit edildi? Bunun imkansız olduğunu düşündüm ... Ha, oh iyi. PrtScn ve SysRq benim için çalışmıyor, ancak bu iki tuş için Fn + End ve Fn + Home kullanan küçük bir klavyeye sahip bir dizüstü bilgisayardayım.
ETHproductions

Bu cevabı seviyorum ama bazı problemleri var gibi görünüyor. Codepen.io/anon/pen/MoLPQM adresinde test ettiğimde Tab benim için hiçbir şey bildirmiyor . Ayrıca F12, PrtScn bu kurala uymuyor "Aldığı tuş basışlarından başka bir işlem yapmamalı ve benzersiz tanımlayıcıdan başka bir şey çıkarmamalı."

@ Html kullanarak, sistemin anahtarı kullanmasını önlemek mümkün değildir. Makine (veya sistem) etkili bir dille (belki C gibi) anahtar girişleri tanımaya zorlamalısınız. Ve sekme için, hangi koşulları çalışmak için bilmiyorum (yani, bazen çalışıyor ve bazen çalışmıyor, cevabımın geçilebilir anahtarları nasıl ele aldığını bilmiyorum.
V. Courtois

@Lembik Kodu bağımsız bir sayfada (snippet, keman veya benzeri değil), tam ekran sayfasında (örneğin, F11 ile) görüntülerseniz, Sekmeleri yakalar; sekmeleri yakalamaması, sayfada çalıştırılan kodun değil, daha büyük tarayıcı ortamının durumunun bir işlevidir. Varsayılan davranışları önlemeye yönelik olarak, <body onkeydown=return!!alert(event.code)>döndürerek hile yapmak gerekir falseüzerindekeydown
apsillers

8

Tcl / Tk, 22 karakter

bind . <Key> {puts %K}

Örnek çalışma:

keys identified by Tcl/Tk

Notlar:

  • Hiçbir sağ Windows tuşu klavyemden ☹ ( akıllı tasarımcı onun yerine arka ışık anahtarını koymak)
  • Sayısal tuş takımı Ekle, NumLock'un durumuna göre farklı kod üretir
  • Ses düğmesi X.org'a özgü kodlar oluşturur, diğerlerinin tümü sadece normal anahtarlardır

6

X.org ile 21 bit

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

Ne yazık ki, Linux'ta MacBook'ta olduğum için test edemiyorum - PrntScr yok, sayısal klavye yok ve hepsi.

xevaltında fare ve klavye olayları çıkaran bir araçtır X.org. Ben awk boruları, hatta satırları filtre (çünkü her tuşa basıldığında ve sonra serbest bırakıldığında gösterilir) ve sadece içerenleri seçin (k- bu dize basılan tuşu açıklayan her satırda.


Soruda listelenen örnek çıktıları ekleyebilir misiniz lütfen.

1
@Lembik tüm çıkışlar çıktıktan sonra görünür.
enedil

Ah. Spesifikasyonun istediği bu değil. Bunu şimdi temizleyeceğim.

Bu, şimdi bir sözdizimi hatası veriyor.

3
Linux'un X11'i ima etmediğini unutmayın. örneğin, bu bir metin konsolunda ( showkey -sorada kullanın : P) veya saf Wayland GUI masaüstünde çalışmaz . Bu gerçekten bir bash + Xorg cevabı.
Peter Cordes

5

Cı ve Win32, 240 224 216 205 202 194 191 bayt

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

çıktılar

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

açıklama

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

Düzenlemeler

-16 @ugoren sayesinde

-8: 10 üyenin tamamı 4 bayt olduğu WNDCLASSiçin intdiziye değiştirildi

-11: wndclass veri dizisinin kısmi başlatılması, 9 öğeye indirgenmesi

-3: intwndclass-data dizisi için örtülü decl kullan

-8: çıkış satırından satırsonu kaldır (spec ve printf yıkamalarında onsuz gerekli değildir); hareket RegisterClassiçine CreateWindowgeri kullanılarak, arg ATOM; wndclass adını olarak ayarlam geçerli bir dize olması için sadece sıfır bayt gerektiren bir .

-3: veriler wiçin yeniden varMSG


Aynı şeyi co ++ kullanarak C ++ ile yapmak çok daha kısa olmaz mı?
onurcanbektas

<iostream>+ Hayır std::cout<<a^b<<"\n". Daha uzun. Artı, işlev etiketlerine dönüş türleri eklemeniz gerektiğini düşünüyorum ve mörtük olamazdı int.
MooseBoys

for(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
İle

Ayrıca p(x,y,a,b)ve (void*)pbazı kaydetmek gerekir.
ugoren

3

Java (OpenJDK 8) , 369 bayt

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

Grafik arayüzü kullandığından TIO ile çalıştırılamaz, ancak bilgisayarımda çalışır.

Duraklat: 153
Girin: 81
NumPad gir: 84
Sol Süper tuş: 193 (Masaüstüm için Menü kısayolunu devre dışı bıraktıktan sonra)
Sağ Süper anahtar: 201
Ekle: 241
Numpad'a takın: 522948 (Bir tane yok, ancak Num lock kapalı 5'e bastığınızda elde ettiğiniz şey budur. Num lock açıkken 812 elde edersiniz.)

Kurtulmamış / Açıklama:

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

Sekme tuşu için işe yaramıyor gibi görünüyor mu?
Poke

setFocusTraversalKeysEnabled(false);cevabınızda bunu düzeltir.
Sihirli Ahtapot Urn

@MagicOctopusUrn Ne yaptığını bilmiyorum ve istediğimi sanmıyorum: P
musicman523

Yanıtınızın SEKME tuşu için çalışmasını sağlar, çünkü cevabınız onsuz geçersizdir.
Sihirli Ahtapot Urn

Ohhhhh Anlıyorum - Tab bir "odaklama çapraz anahtarı"
musicman523

3

Scala 2.10+, 279 karakter, 279 bayt

Şimdi bu bir scala yanıtı :) Java yapıyormuşum gibi hissettiriyor. Neyse biz TIO üzerinde test edemiyoruz.

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

Kullanmasak bile tüm kalıtsal yöntemleri bildirmemiz üzücü: l Bazı derleyici bayrakları bunları bildirmemeye izin verebileceğinden, bunları bayt sayımından kaldırabilir miyim?

Bu (benim html-js yanıtı gibi) keyPressed, "-" ve sonra onun "konumu" yazdırır.

Örneğin :

PrtScn -> doğrulanamıyor
Kaydırma Kilidi -> 145-1
Duraklat -> 19-1
sol Shift -> 16-2
sağ Shift -> 16-3
sol Ctrl -> 17-2
sağ Ctrl -> 17-3
Caps Kilidi -> 20-1
Sekme -> doğrulanamıyor
Enter -> 10-1
Sayısal tuş takımına girin -> 10-4
Sayı Kilidi -> 144-4
Ekle ->
Sayısal tuş takımında 96-1 Ins -> 96-4
Geri tuşu -> 8-1
Del -> 127-1
F1 ... F12 -> 112-1 - 123-1
Esc -> 27-1
sol Windows tuşu -> 524-2
sağ Windows tuşu -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (bir tür hata, 17-2 ve sonra 18-3'ü algılar,ama gerçekten 18-3)
uygulama anahtarı (bağlam menüsü) -> 525-1

Bence bilgisayara bağlı olsa da: / Şu anda bir dizüstü bilgisayar kullanıyorum.


Gereksiz bildirimleri saymak istemiyorsanız, standart olmayan derleyici bayraklarının uzunluğunu eklemeniz gerekebilir. Eski derleyiciler varsayılan olarak bunu kullanmazsa? -std=c89Modern derleyiciler varsayılan olarak c99 veya c11 olduğundan C cevaplarının derlenmesi gerekir , ancak bunu saymaya gerek yoktur. Yani kod golf meta karar ne olacağını emin değilim.
Peter Cordes

3

TI-BASIC, 19 bayt

PROGRAM: S

If Ans
Disp Ans
getKey
prgmS
  • Girin: 105,
  • Sol tuş: 24,
  • Sağ tuş: 26,
  • Ins [ert] biraz farklıdır, çünkü normalde ulaşmak için iki tuşa basmak gerekirdi, ancak bunlar 21, ardından 23 olacaktı.

İşte tuşların geri kalanının bir örneği:

resim açıklamasını buraya girin

Açıklama:

PROGRAM: S Editör, adı kodun dışında en üstte görüntüler; adı "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

Ne yazık ki, Arnold C'de bunu yapmak mümkün değil, bu yüzden TI-BASIC'e bağlı kalmalıydım.


1
Bu resimdeki her tuş için çalışıyor mu? Değilse hangi tuşlar başarısız olur?

2
Evet, hesap makinesi dışında bir pil patlatmadan programı öldürmek için ayrılmış on düğmesi hariç her tuş için çalışır.
bearacuda13 15:17

@ bearacuda13: 18 yıl önce satın aldığım ve yıllardır AÇIK anahtar detayını bilmediğim eşit bir hesap makinem var. Üniversitenin sonundan beri kullanıyordum (11 yıl önce), ama kim bilir ...
sergiol

1

C #, 144 + 601 = 745 bayt

İki sınıftan oluşur, onları bir sınıfta başarıyla birleştirmeyi başaramadım.

Ana sınıf:

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

Kanca sınıfı:

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

Çıktılar:

  • Sekme: 137
  • Duraklat: 147
  • Giriş: 141
  • NumPad Gir: 142
  • Sol Windows: 220
  • Sağ Windows: 221
  • ekle: 174
  • NumPad Ekleme: 224

Ben değiştirerek biraz aşağı bayt alabilirsiniz ||etmek |ve diğer benzer golfs ama beynim bunu yaparken sonra dinlenmeye ihtiyacı!
TheLethalCoder

Hook sınıfında, bence public int v;public int c;public int f;kısaltılabilirpublic int v,c,f;
Question Marks

@QuestionMarks Bir bilgisayara geri döndüğümde iyi fikir golf olacak
TheLethalCoder

1

AutoHotkey , 26 Bayt

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

Test edilemez (yalnızca kazanma), ancak Mseçenek

M: Control-A - Control-Z gibi değiştirilmiş tuş vuruşları tanınır ve gerçek ASCII karakterlerine karşılık gelirse kopyalanır.

Bu yüzden iyi olmalı.


1

WinApi C ( gcc ), 156 bayt

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

Bu program , girişin her klavye tuşu ile ayrılmış Windows Sanal Anahtar Kodunu yazdırır. \nİçinde printfbiçim-string isteğe bağlıdır (ancak insan dostu çıktı yapar) ve toplam puan için bırakılabilir 154 bayt . Programı (taskmgr olmadan) öldürmenin kolay bir yoludur CTRL + PAUSE. Fn tuşlu bir klavyeniz varsa, Windows tarafından fark edilmediğinden bu program onu ​​alamaz.

  • MooseBoys'un hileye cevabı #include <d3d.h>veBYTE dizi .

Yerel değişkenler, okunabilirlik ve derleyici uyarıları olmayan program şöyle görünür:

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

1

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

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

Kod, odak kaybolduktan sonra bile tuşları yakalar.

Aşağıdaki ekran görüntüleri printf("%d ",j);daha iyi okunabilirlik için çıkışlar arasına boşluk ekleyerek kaydedilir ( +1 bayt):

anahtar ekran görüntüsü

Left-ctrl Left-win Left-alt Space Right-alt Right-win Right-menu Right-ctrl Left-shift Z X C Right-shift Left-shift 1 2 3 Num 1 Num 2 Num 3 Left-shift +/= (on the main part) Num + Left-alt PrtScn

Kod GetAsyncKeyState, genellikle diğer kullanıcı modu yaklaşımlarından (DirectInput hariç) daha gerçek zamanlı olan ileti sırasını denetlemeden anahtar durumunu sorgulamak için kullanır . Bu yaklaşım tuş kaydedicilerde yaygın olarak kullanılmaktadır.

(j<16||j>18)Ctrl / Alt / Shift tuşlarına düzenli olarak filtre uygular. 16/17/18 konum belirtilmiş vkey değeri ile birlikte sol veya sağ tuşlara basıldığında tetiklenir.


1

PowerShell, 34 bayt

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

Çıktılar girişle aynı satırda, bu biraz kafa karıştırıcı olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.