QB64 Phoenix Edition
Don't let INKEY$ byte you in the ASCII - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: Chatting and Socializing (https://qb64phoenix.com/forum/forumdisplay.php?fid=11)
+--- Forum: General Discussion (https://qb64phoenix.com/forum/forumdisplay.php?fid=2)
+--- Thread: Don't let INKEY$ byte you in the ASCII (/showthread.php?tid=4439)



Don't let INKEY$ byte you in the ASCII - Pete - 02-01-2026

I mostly love INKEY$, but we can't rely on it to accurately report a key was not released. So here are some observations. The last example is a Combined Inkey$ and _Keyhit solution.

Hold down the "A" key and don't release it. See, INKEY$ says it was released!
Code: (Select All)
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        If a$ <> b$ Then a$ = b$: Print a$ + " was pressed."
    Else
        If Len(a$) Then Print a$ + " was released.": a$ = ""
    End If
Loop

Now a jerkaround is to add a delay. This works, but sucks...

Code: (Select All)
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        If a$ <> b$ Then a$ = b$: Print a$ + " was pressed.": _Delay .5
    Else
        If Len(a$) Then Print a$ + " was released.": a$ = ""
    End If
Loop

That's right. At least in my system anything less than a half-second delay fails! Imagine typing with a half-second delay.

So to ease the delay situation, we create a mock buffer and time it. (This is what I had to do before QB64).

Code: (Select All)
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        If a$(cnt) <> b$ Then cnt = cnt + 1: a$(cnt) = b$: Print a$(cnt) + " was pressed.": z1 = Timer
    Else
        If Len(a$(cnt)) And Abs(z1 - Timer) > .49 Then
            Print a$(cnt) + " was released.": a$(cnt) = "": cnt = cnt - 1
        End If
    End If
Loop

I know, I know. I didn't bother to dim the array (buffer), so it will fail after 10 here, and I didn't bother to do a complete 24-hour timer, so it would fail once at mid-night, but I'm keeping it as simple coded as possible for this discussion.

Anyway, all this crap can be avoided using the _KeyHit method or by adding _KeyHit to the Inkey$ routine.

_KeyHit Method
Code: (Select All)
Do
    _Limit 30
    k = _KeyHit
    If k > 0 Then
        If j <> k Then j = k: Print j; "was pressed."
    ElseIf k < 0 Then
        If j Then Print j; "was released.": j = 0
    End If
Loop

And finally, our combined INKEY$ with _KEYHIT solution...

_KeyHit used with Inkey$ Method
Code: (Select All)
Do
_Limit 30
b$ = InKey$
k = _KeyHit
If k < 0 Then Print a$ + " was released.": a$ = ""
If Len(b$) And a$ <> b$ Then a$ = b$: Print a$ + " was pressed."
Loop

Just some food for thought for anyone who will need to monitor a key release like a same key tapping routine.

Pete


RE: Don't let INKEY$ byte you in the ASCII - PhilOfPerth - 02-01-2026

Nice one,  @Pete. Compact and simple. I'll be adapting  the clumsy "Response" in my programmes with this. Thanks.