'=========================================================================== ' Subject: DETECT KEYDOWN & KEYUP EVENTS Date: 04-11-96 (18:17) ' Author: Eric Benson Code: QB, QBasic, PDS ' Origin: comp.lang.basic.misc Packet: KEYBOARD.ABC '=========================================================================== 'This routine I wrote to detect keydown and keyup events works great (using 'INP(&H60) as someone suggested a while back). To get the ascii of the key that 'was pressed I am using INKEY$. It sometimes returns zero, I guess the BIOS 'hasn't translated the key when I call INKEY$. But if you run the program 'below you may notice a fairly substantial (0.5 sec) delay sometimes. 'Suggestions to get around this? 'I figure I could load an array with ascii codes and index it with the scancode 'i.e. ascii=scan2ascii(scancode), but I would still need to take care of the 'shift key. 'Or maybe I should run this in straight DOS and not in a Win95 DOS box. 'Program Keypress.bas by Eric Benson - April 1996 DEFINT A-Z DECLARE SUB KernelKeyPress (scancode AS INTEGER, ascii AS INTEGER, keystate AS INTEGER) REM DECLARE SUB BYTECOPY (SEG SOURCE AS ANY, SEG DESTINATION AS ANY, NUMBYTES&) CONST TRUE = -1, FALSE = 0 CONST keybuffermax = 10, kdown = 1, kpressed = 2, kup = 3 TYPE keyvar keyin AS INTEGER keyup AS INTEGER scancode AS INTEGER ascii AS INTEGER extended AS INTEGER END TYPE CLS REM GOTO test DO keystate = 0 KernelKeyPress scancode, ascii, keystate IF keystate = kdown THEN PRINT "keydown "; scancode, ascii ELSEIF keystate = kup THEN PRINT "keyup "; scancode, ascii END IF LOOP UNTIL scancode = 1 END test: 'used to look at what the keyboard is outputing DO keyin = INP(&H60) ' LOCATE 1, 1: PRINT " " LOCATE 1, 1: PRINT keyin b$ = INKEY$ LOOP UNTIL keyin = 1 END SUB KernelKeyPress (scancode AS INTEGER, ascii AS INTEGER, keystate AS INTEGER) STATIC init AS INTEGER, buffer() AS keyvar STATIC ibuf AS INTEGER, pressedkey AS INTEGER IF init THEN keyin = INP(&H60) b$ = INKEY$ 'Warning inkey$ above does not always trap the keystroke IF keyin > 128 AND pressedkey THEN FOR i = 1 TO ibuf IF keyin = 170 OR buffer(i).keyup = keyin THEN scancode = buffer(i).scancode ascii = buffer(i).ascii keystate = kup IF ibuf = 1 THEN pressedkey = 0 ELSEIF i < ibuf THEN pressedkey = buffer(i).keyup FOR j = i TO ibuf - 1 SWAP buffer(j), buffer(j + 1) NEXT REM BYTECOPY buffer(i + 1), buffer(i), (ibuf - i) * 10 ELSE 'top key in buffer is unpressed pressedkey = buffer(i).keyup END IF ibuf = ibuf - 1 EXIT SUB END IF NEXT END IF IF pressedkey <> keyin AND keyin < 129 THEN IF ibuf THEN FOR i = 1 TO ibuf IF buffer(i).keyin = keyin THEN EXIT SUB NEXT END IF IF ibuf < keybuffermax THEN ibuf = ibuf + 1 buffer(ibuf).keyin = keyin buffer(ibuf).keyup = keyin + 128 'Remove this IF..ENDIF block for normal execution 'Will hang if shift is pressed IF LEN(b$) = 0 THEN DO b$ = INKEY$ LOOP UNTIL LEN(b$) END IF IF LEN(b$) = 2 THEN buffer(ibuf).extended = ASC(RIGHT$(b$, 1)) ELSEIF LEN(b$) THEN buffer(ibuf).ascii = ASC(b$) ELSE buffer(ibuf).ascii = 0 END IF buffer(ibuf).scancode = keyin pressedkey = keyin scancode = keyin ascii = buffer(ibuf).ascii keystate = kdown EXIT SUB END IF END IF ELSE DIM buffer(1 TO keybuffermax) AS keyvar ibuf = 0 pressedkey = 0 init = TRUE END IF END SUB