Tôi đã nhấn phím nào?


15

Nhiệm vụ là viết mã để xác định phím nào được nhấn trên bàn phím. Bạn có thể giả sử rằng chỉ có một phím được nhấn tại một thời điểm và có bố cục bàn phím tiêu chuẩn của Hoa Kỳ. Đó là cách bố trí với @ trên 2.

Mã của bạn sẽ xuất ra một mã định danh duy nhất cho bất kỳ phím nào được nhấn. Điều này bao gồm PrtScn, Scroll Lock, Tạm dừng, Shift trái, Shift phải, Ctrl trái, Ctrl phải, Caps Lock, Tab, Enter, Enter trên bàn phím số, Num Lock, Chèn, Ins trên bàn phím số, Backspace, Del, F1 ... F12, Esc, phím Windows trái, phím Windows phải, Alt, AltGr, phím ứng dụng (menu ngữ cảnh), v.v.

Mã của bạn sẽ tiếp tục chờ nhấn phím và xuất ra danh tính của chúng cho đến khi nó bị giết. Tuy nhiên, nó sẽ xuất ra mã định danh ngay khi một khóa được phát hành. Nó không nên thực hiện bất kỳ hành động nào khác từ các lần nhấn phím mà nó nhận được và nó không nên xuất ra bất cứ thứ gì ngoài số nhận dạng duy nhất.

Trong câu trả lời của bạn, vui lòng hiển thị những gì bạn mã đầu ra cho các lần nhấn phím sau: Tab, Tạm dừng, Enter, Enter trên bàn phím số, phím Windows bên trái, phím Windows phải, Chèn và Ins trên bàn phím số.

Nếu bạn có một bàn phím rất khác, thách thức vẫn là xuất ra một mã định danh khác nhau cho mỗi phím trên bàn phím của bạn.


1
Trong JS (dù sao trình duyệt JS), không thể kiểm tra xem một số phím nhất định có được nhấn hay không (ví dụ: Caps Lock, Num Lock, Scroll Lock, PrtScn). Điều này có nghĩa là JS không thể trả lời?
Sản xuất ETH

2
@ETHproductions Nó thực sự. Xin lỗi những người yêu thích JS ở khắp mọi nơi.

2
Yêu cầu sửa đổi sau 5 câu trả lời được cung cấp (bao gồm một câu trả lời hiện đã bị xóa). Điều đó không thực sự công bằng ...
Olivier Grégoire

6
Tôi không nghĩ việc yêu cầu đầu ra cho các phím không có trên nhiều bàn phím như phím Windows, v.v.
Notts90

1
@ Notts90 Chúng không phải là một phần của bố cục bàn phím tiêu chuẩn của Hoa Kỳ? tải lên.wikierra.org/wikipedia/commons/thumb/5/51/ từ

Câu trả lời:


22

Mã máy x86, thực thi DOS, 29 * 28 byte

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Đây là một COM thực thi cho MS-DOS , nó yêu cầu phần cứng tương thích với PC của IBM .
Đặc biệt là bộ điều khiển 8042 PS / 2 hoặc nhiều khả năng là mô phỏng của nó thông qua SMM .
Tóm lại, nó sẽ hoạt động tốt trong bất kỳ PC chính thống nào.

Mã nguồn là

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

Tôi đã chia chương trình thành hai phần.

Phần đầu tiên liên quan đến việc đọc các scancodes . Scancodes là các giá trị số được liên kết với mọi khóa.
Lưu ý rằng đây là mã phần cứng, chúng không phụ thuộc vào HĐH hoặc bộ ký tự. Chúng giống như một cặp được mã hóa (cột, hàng) của khóa.
Mỗi phím đều có một scancode, ngay cả những phím chức năng kỳ lạ không chuẩn được tìm thấy trên một số bàn phím (ví dụ: phím "open calc").
Một số khóa có scancode nhiều byte, chúng có các tiền tố được thiết kế để làm cho luồng có thể giải mã được bằng cách chỉ nhìn vào chuỗi byte.
Vì vậy, mỗi khóa được nhận dạng duy nhất, thậm chí CTRL, SHIFT, WinKeys, v.v.

Chỉ "mã phá vỡ", được gửi khi một khóa được giải phóng, được xử lý, "tạo mã" bị bỏ qua.
Các trình định dạng có tập bit cao hơn (bit 7 cho một byte), vì vậy thật dễ dàng để nhận ra chúng.

Phần thứ hai liên quan đến việc in một byte.
In ấn luôn luôn dài trong lắp ráp, chúng tôi không có nội dung.
Để giữ cho nó ngắn và vì được yêu cầu viết mã định danh của khóa, tôi đã bỏ các chữ số thập phân hoặc thập phân có lợi cho mã hóa cá nhân.

Một byte xy, trong đó x là nibble cao hơn và y thấp hơn được in thành hai ký tự liên tiếp c 0 và c 1 được định nghĩa là:

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

Lưu ý rằng nibble thấp hơn được in trước (điều này tránh cho tôi một trao đổi).
Lý do là để ánh xạ từng trong số 16 giá trị có thể có của một cây bút chì thành các ký tự ASCII liên tiếp từ '!'.
Đơn giản chỉ cần đặt đây là một số hex nhưng với

  1. Các ngòi nổ
  2. !"#$%&'()*+,-./01 như chữ số (als) thay vì 0123456789abcdef

Chạy nó trong DOSBox và nhấn một số khóa ngẫu nhiên (một số trong số đó là một khóa đặc biệt nhưng lưu ý rằng trong quá trình Windows, DOSBox không thể nắm bắt tất cả các khóa)

DOSBox chạy mã định danh khóa

Lưu ý rằng chương trình này không bao giờ chấm dứt (hơn nữa, nó kiểm soát hoàn toàn PC bằng cách vô hiệu hóa các ngắt) như tôi tin là do câu hỏi dự định (đơn giản là không có quá trình giết chết các tiến trình trong DOS).


* Giảm cảm ơn CodyGray .


Có phải việc sử dụng INhướng dẫn đã nhỏ hơn về số byte so với việc gọi các ngắt ROM ROM (ví dụ int 16h, chức năng 10h)?
Cody Grey

@CodyGray Rất có thể là không, toàn bộ vòng lặp có thể bị bỏ qua. Bằng cách nào đó tôi chỉ cần nhảy thẳng vào inhướng dẫn. Đó thực sự là một điểm rất tốt mà bạn có. Nếu bạn chưa có, tại sao không đăng nó như một câu trả lời? :)
Margaret Bloom

1
Bây giờ bạn đang nói chuyện điên rồ! Nghe có vẻ như nhiều công việc hơn là chỉ nhận xét về câu trả lời hiện có của bạn. :-p Tôi đang chơi với việc đặt một cái gì đó cùng nhau. Mặc dù vậy, mẹo thú vị: khi chơi golf mã, xchgvới bộ tích lũy là một trong các thanh ghi là 1 byte, do đó, tốt hơn so với 2 byte mov.
Cody Grey

1
Được rồi, vấn đề int 16hlà tôi không nhận được mã quét cho các phím shift, khóa cuộn hoặc tạm dừng / ngắt (có lẽ là các mã khác) và đó là yêu cầu bắt buộc của thử thách. Giải pháp đọc đầu vào trực tiếp từ I / O hoạt động, mặc dù đối với tôi, nó trả về cùng một giá trị cho tất cả các khóa trong cụm Ins / Del / Home / End / PGUp / PGDown.
Cody Grey

1
@PeterCordes: PAUSE cũng có một số hành vi lạ, IIUC gửi mã phá vỡ cùng với mã tạo khi nhấn phím và không gửi bất cứ điều gì khi phát hành khóa. Hoặc đó là những gì tôi hiểu từ bách khoa toàn thư lập trình trò chơi PC.
ninjalj

12

Java 7 trở lên, 246 228 byte

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

Ung dung:

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 nhờ @ OlivierGrégoire cho show(), 0<0import java.awt.event.*;

Kết quả nào trong:

nhập mô tả hình ảnh ở đây

Thậm chí xử lý các phím bấm cho các ký tự viết hoa, phím cửa sổ, khóa nắp, v.v ... Bạn cũng có thể thấy nó in 'bộ sửa đổi', đó là 'phím giữ'.

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

Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Dennis

11

HTML (với Javascript), 46 31 ký tự, 46 31 byte

Sử dụng điều này để phân biệt nhập và trả lại numpad, LControl và RControl ... Không còn nữa vì các apsillers đã tìm ra cách để thực hiện điều đó bằng một lệnh gọi chức năng đăng nhập.

<body onkeyup=alert(event.code)

Đầu ra cụ thể:

NGOÀI RA VẬY, VẪN CÒN VỚI NHỮNG CON SỐ NÀY TÔI KHÔNG THỂ KIỂM TRA LAPTOP CỦA TÔI
XIN VUI LÒNG ĐỂ TÔI CÓ TIẾP CẬN

PrtScn -> PrintScreen
Scroll Lock -> ScrollLock
Tạm dừng -> Tạm dừng
Shift trái -> ShiftLeft
phải Shift -> ShiftRight
trái Ctrl -> ContrlLeft
phải Ctrl -> ControlRight
Caps Lock ->
Tab CapsLock -> Tab
Enter -> Enter
Enter trên số pad -> Numpad Entry
Num Lock -> NumLock
Chèn -> Chèn
Ins trên bàn phím số -> Numpad0
Backspace -> Backspace
Del -> Xóa
F1 ... F12 -> F1 đến F12
Esc -> Thoát khỏi phím
Windows bên trái -> MetaLeft
phải Phím Windows -> Khóa ứng dụng MetaRight (menu ngữ cảnh) -> ContextMothy
Alt -> AltLeft
AltGr -> AltRight (loại lỗi, nó phát hiện ControlLeft và sau đó là AltRight,nhưng nó thực sự là AltRight)

EDIT:
1 byte được lưu ;sau khi func gọi
18 byte được lưu nhờ Lil 'Bits và ETHproductions, họ nhận thấy tôi quên rút ngắn tên func và var.
32 byte được lưu nhờ RogerSpielker, anh ấy nhận thấy tôi đang thực hiện mã sparated mà không có lý do; và một lần nữa -2 byte: onkeydown-> onkeyup
Đã lưu 1 byte: không cần gạch chéo cuối cùng được
lưu 2 byte nhờ CraigAyre: with()chức năng được
lưu 2 byte chỉ nhờ ASCII: keythay vì which
4 byte được lưu, vì chúng tôi có văn bản, không cần for '-'+(mỗi mã định danh là duy nhất không có cái này) 1 byte được lưu chỉ nhờ ASCII (một lần nữa): không còn ký hiệu đóng > 15 byte nào được lưu nhờ vào bộ trả lời, như đã nói ở đầu câu trả lời của tôi.

<body onkeyup=alert(event.code)


Đợi ... làm thế nào ... Caps Lock ... được phát hiện? Tôi nghĩ điều đó là không thể ... Huh, oh tốt. PrtScn và SysRq không hoạt động với tôi, nhưng tôi đang sử dụng máy tính xách tay có bàn phím nhỏ sử dụng Fn + End và Fn + Home cho hai phím đó.
Sản phẩm ETH

Tôi thích câu trả lời này nhưng dường như có một số vấn đề. Tab không báo cáo bất cứ điều gì cho tôi khi tôi kiểm tra nó tại codepen.io/anon/pen/MoLPQM . Ngoài ra F12, PrtScn không tuân theo quy tắc này "Không nên thực hiện bất kỳ hành động nào khác từ các lần nhấn phím mà nó nhận được và không nên xuất bất cứ thứ gì ngoài số nhận dạng duy nhất."

@Lembik sử dụng html, thực sự không thể ngăn hệ thống sử dụng khóa. Bạn cần buộc nó không nhận ra các đầu vào chính bằng ngôn ngữ hiệu quả của máy (hoặc hệ thống) (như C có thể). Và đối với tab, tôi không biết điều kiện nào để làm việc (ý tôi là, đôi khi nó hoạt động và đôi khi không, tôi không biết câu trả lời của mình xử lý các khóa có thể vượt qua như thế nào.
V. Courtois

@Lembik Nếu bạn xem mã dưới dạng độc lập (không phải là đoạn trích hoặc fiddle hoặc tương tự), trang toàn màn hình (ví dụ: với F11) thì nó sẽ chụp Tab; thực tế là nó không chụp các tab là một chức năng của trạng thái môi trường trình duyệt lớn hơn, không phải là mã đang được chạy trên trang. Như để ngăn ngừa các hành vi mặc định, <body onkeydown=return!!alert(event.code)>nên làm các trick bằng cách quay falsevềkeydown
apsillers

8

Tcl / Tk, 22 ký tự

bind . <Key> {puts %K}

Chạy mẫu:

các khóa được xác định bởi Tcl / Tk

Ghi chú:

  • Không có phím Windows bên phải trên bàn phím của tôi ( nhà thiết kế thông minh đặt công tắc đèn nền ở vị trí của nó)
  • Chèn số của bàn phím số tạo mã khác nhau dựa trên trạng thái của NumLock
  • Núm âm lượng tạo ra các mã cụ thể X.org, tất cả các loại khác chỉ là các phím bấm thông thường

6

Bash với X.org, 21 byte

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

Thật không may, tôi không thể kiểm tra nó vì tôi đang dùng MacBook trên Linux - không có PrntScr, không có bàn phím số & tất cả.

xevlà một công cụ xuất ra các sự kiện chuột và bàn phím theo X.org. Tôi chuyển nó thành awk, lọc các dòng chẵn (vì mọi phím được hiển thị khi nhấn phím và sau đó khi nó được giải phóng) và chỉ chọn những dòng có chứa (k- chuỗi này nằm trong mỗi dòng mô tả phím được nhấn.


Bạn có thể thêm các kết quả đầu ra được liệt kê trong câu hỏi xin vui lòng.

1
@Lembik tất cả đầu ra xuất hiện sau khi thoát.
enedil

Ah. Đó không phải là những gì thông số kỹ thuật yêu cầu. Tôi sẽ xóa nó ngay bây giờ.

Điều này đưa ra một lỗi cú pháp bây giờ.

3
Lưu ý rằng Linux không ngụ ý X11. ví dụ: điều này sẽ không hoạt động trên bảng điều khiển văn bản (sử dụng showkey -sở đó: P) hoặc trên màn hình nền Wayland GUI thuần túy. Đây thực sự là một câu trả lời bash + Xorg.
Peter Cordes

5

C và Win32, 240 224 216 205 202 194 191 byte

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

Đầu ra

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

Giải trình

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

Chỉnh sửa

-16 cảm ơn @ugoren

-8: đổi WNDCLASSthànhint mảng vì tất cả 10 thành viên là 4 byte

-11: khởi tạo một phần mảng dữ liệu wndgroup, giảm xuống còn 9 phần tử

-3: sử dụng ngầm int từ chối cho mảng dữ liệu wndgroup

-8: xóa dòng mới khỏi định dạng đầu ra (không bắt buộc trong spec và printf tuôn ra ngay lập tức mà không có nó); di chuyển RegisterClassvào CreateWindowarg, sử dụng trả lại ATOM; đặt tên wndgroup thànhm mà chỉ cần một byte 0 trong đó là một chuỗi hợp lệ.

-3: sử dụng lại wvar cho MSGdữ liệu


Làm điều tương tự với C ++ bằng cách sử dụng cout sẽ không ngắn hơn nhiều?
onurcanbektas

@Leth số <iostream>+ std::cout<<a^b<<"\n"dài hơn. Thêm vào đó, tôi nghĩ rằng bạn cần thêm các kiểu trả về cho hàm giảm dần và mkhông thể là ẩn int.
MooseBoys

Lưu một char vớifor(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
ugoren

Ngoài ra, p(x,y,a,b)(void*)pnên tiết kiệm một số.
ugoren

3

Java (OpenJDK 8) , 369 byte

import java.awt.event.*;import javax.swing.*;class F{public static void main(String[] a){JFrame f=new JFrame();f.addKeyListener(new KeyListener(){public void keyPressed(KeyEvent e){System.out.print(e.getKeyCode()*8+e.getKeyLocation());}public void keyTyped(KeyEvent e){}public void keyReleased(KeyEvent e){}});f.setVisible(true);f.setFocusTraversalKeysEnabled(false);}}

Điều này không thể chạy với TIO vì nó sử dụng giao diện đồ họa, nhưng nó hoạt động trên máy tính của tôi.

Tạm dừng: 153
Nhập: 81
Nhập vào NumPad: 84
Phím Super trái: 193 (Sau khi tắt phím tắt Menu cho máy tính để bàn của tôi)
Phím siêu phải: 201
Chèn: 241
Chèn vào Numpad: 522948 (Tôi không có, nhưng đó là những gì bạn nhận được khi nhấn 5 với khóa Num. Khi khóa Num được bật, bạn nhận được 812.)

Ungolfed / Giải thích:

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

Không giống như nó hoạt động cho phím tab?
Chọc

setFocusTraversalKeysEnabled(false);trong câu trả lời của bạn sẽ khắc phục điều này.
Bạch tuộc ma thuật Urn

@MagicOctopusUrn Tôi không biết điều đó làm gì và tôi không nghĩ mình muốn: P
musicman523

Nó làm cho câu trả lời của bạn hoạt động với khóa TAB, vì câu trả lời của bạn không hợp lệ nếu không có nó.
Bạch tuộc ma thuật Urn

Ohhhhh tôi thấy - Tab là "chìa khóa truyền tải tập trung"
sĩ523

3

Scala 2.10+, 279 ký tự, 279 byte

Bây giờ đây là một phản hồi scala :) mặc dù cảm giác như tôi đang làm Java. Dù sao, chúng tôi không thể kiểm tra nó trên 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){}})}}

Thật đáng buồn khi chúng ta cần khai báo tất cả các phương thức được kế thừa ngay cả khi chúng ta không sử dụng chúng: Tôi có thể xóa chúng khỏi số byte không, vì một số cờ trình biên dịch có thể cho phép không khai báo chúng không?

Điều này in (như đối với phản hồi html-js của tôi) keyPress, "-" và sau đó là "vị trí" của nó.

Ví dụ :

PrtScn -> không thể xác minh
Khóa cuộn -> 145-1
Tạm dừng -> 19-1
Shift trái -> 16-2
Shift phải -> 16-3
Ctrl trái -> 17-2
Ctrl phải -> 17-3
Caps Lock ->
Tab 20-1 -> không thể xác minh
Enter -> 10-1
Enter trên bàn phím số -> 10-4
Num Lock -> 144-4
Chèn -> 96-1
Ins trên bàn phím số -> 96-4
Backspace -> 8-1
Del -> 127-1
F1 ... F12 -> 112-1 đến 123-1
Esc -> 27-1
phím Windows trái -> 524-2 Phím
Windows phải -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (loại lỗi, nó phát hiện 17-2 và sau đó 18-3,nhưng nó thực sự là
khóa ứng dụng 18-3 (menu ngữ cảnh) -> 525-1

Mặc dù tôi nghĩ rằng nó phụ thuộc vào máy tính: / Tôi đang sử dụng máy tính xách tay.


Nếu bạn muốn không tính các khai báo không cần thiết, bạn có thể phải bao gồm độ dài của các cờ biên dịch không chuẩn. Trừ khi trình biên dịch cũ được sử dụng để mặc định đó? Câu trả lời C thường cần được biên dịch -std=c89vì trình biên dịch hiện đại mặc định là c99 hoặc c11, nhưng không cần phải tính điều đó. Vì vậy, tôi không chắc phán quyết sẽ là gì từ meta-golf-code.
Peter Cordes

3

TI-BASIC, 19 byte

CHƯƠNG TRÌNH: S

If Ans
Disp Ans
getKey
prgmS
  • Nhập: 105,
  • Phím trái: 24,
  • Phím phải: 26,
  • Ins [ert] hơi khác một chút vì thông thường sẽ cần hai lần nhấn phím để đến, nhưng những lần nhấn đó sẽ là 21 sau 23.

Đây là một minh họa cho phần còn lại của các phím:

nhập mô tả hình ảnh ở đây

Giải trình:

CHƯƠNG TRÌNH: S Trình soạn thảo hiển thị tên ở trên cùng ngoài mã; tên là "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

Thật không may, điều này không thể thực hiện được ở Arnold C, vì vậy tôi đã phải gắn bó với TI-BASIC.


1
Nó có hoạt động cho mọi phím trong bức tranh đó không? Nếu không có phím nào thì nó không thành công?

2
Có, nó hoạt động cho mọi phím trừ nút bật, được dành riêng để tắt chương trình mà không cần rút pin ra khỏi máy tính.
bearacuda13

@ bearacuda13: Tôi có một máy tính bằng nhau mà tôi đã mua 18 năm trước và không biết chi tiết khóa ON trong nhiều năm. Tôi đã sử dụng nó từ cuối đại học (11 năm trước), nhưng ai biết được ...
sergiol

1

C #, 144 + 601 = 745 byte

Bao gồm hai lớp, tôi không thể kết hợp thành công chúng thành một lớp.

Lớp chính:

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

Lớp móc:

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

Đầu ra:

  • Tab: 137
  • Tạm ngừng: 147
  • Đi vào: 141
  • Nhập số: 142
  • Windows trái: 220
  • Windows bên phải: 221
  • Chèn: 174
  • Chèn NumPad: 224

Tôi có thể giảm các byte xuống một chút bằng cách đổi ||sang |các golf tương tự khác nhưng não tôi cần nghỉ ngơi sau khi làm điều đó!
TheLethalCoder

Trong lớp Hook, tôi nghĩ public int v;public int c;public int f;có thể rút ngắn thànhpublic int v,c,f;
Dấu hỏi

@QuestionMarks Ý tưởng hay sẽ chơi golf khi tôi quay lại máy tính
TheLethalCoder

1

AutoHotkey , 26 byte

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

Không thể kiểm tra (chỉ giành chiến thắng), nhưng Mtùy chọn cho biết

M: Các tổ hợp phím được sửa đổi như Control-A đến Control-Z được nhận dạng và sao chép nếu chúng tương ứng với các ký tự ASCII thực.

Vì vậy, nó nên làm tốt.


1

WinApi C ( gcc ), 156 byte

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

Chương trình này in ra Mã khóa ảo Windows xác định với mỗi phím bàn phím nhập. Các \ntrongprintf định dạng chuỗi là không bắt buộc (nhưng làm cho con người thân thiện đầu ra) và có thể được giảm với tổng số điểm là 154 byte . Một cách dễ dàng để giết chương trình (không có taskmgr) là với CTRL + PAUSE. Nếu bạn có bàn phím có phím Fn, chương trình này không thể nhận bàn phím vì nó thậm chí không được Windows chú ý.

  • Tín dụng cho câu trả lời của MooseBoys cho #include <d3d.h>mánh khóe và cảm hứng cho BYTEmảng.

Chương trình với các biến cục bộ, khả năng đọc và không có cảnh báo của trình biên dịch trông như thế này:

#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 byte

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

Mã này bắt các phím ngay cả sau khi mất tiêu điểm.

Các ảnh chụp màn hình sau đây được ghi lại thêm khoảng trắng giữa các đầu ra ( printf("%d ",j);+1 byte) để dễ đọc hơn:

ảnh chụp màn hình chính

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

Mã sử ​​dụng GetAsyncKeyStateđể truy vấn trạng thái khóa mà không kiểm tra hàng đợi tin nhắn, thường là thời gian thực hơn các cách tiếp cận chế độ người dùng khác (ngoại trừ DirectInput). Cách tiếp cận này được sử dụng rộng rãi trong keylogger.

(j<16||j>18)lọc Ctrl / Alt / Shift thường xuyên. 17/17/18 được kích hoạt bất cứ khi nào nhấn trái hoặc phải, cùng với giá trị vkey được chỉ định theo vị trí.


1

PowerShell, 34 byte

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

Đầu ra trên cùng một dòng với đầu vào, có thể gây nhầm lẫn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.