I have a problem where ctypes.windll.user32.GetKeyState won't detect keys on my keyboard (A, B, C, e.t.c), but it does detect the left and right mouse buttons.
I am trying to make a simple script which detects the lowercase "a" key. I got the number 97 by doing ord('a')
.
import ctypes
def a_pressed():
return ctypes.windll.user32.GetKeyState(97) > 1
while True:
if a_pressed():
print('a is pressed')
Am I doing something wrong or is it just some limitation of the API that I don't know about?
CodePudding user response:
[MS.Docs]: GetKeyState function (winuser.h) (emphasis is mine):
A virtual key. If the desired virtual key is a letter or digit (A through Z, a through z, or 0 through 9), nVirtKey must be set to the ASCII value of that character. For other keys, it must be a virtual-key code.
is "a bit" misleading.
From ASCII's PoV, there's a clear difference between (for example):
- a: 0x61 (97)
- A: 0x41 (65)
From keyboard's PoV, things are a bit different:
- a: The key on the 3rd row and 2nd column, at the right of CapsLock (on US keyboards) pressed
- A: Same as above, but with either:
- CapsLock on
- Shift pressed
[MS.Docs]: Virtual-Key Codes makes things clear: in order to check the state of A (or a), 0x41 (65) must be checked (97 corresponds to NumPad1).
code00.py:
#!/usr/bin/env python
import sys
import time
import ctypes as ct
from ctypes import wintypes as wt
def main(*argv):
user32 = ct.WinDLL("User32.dll")
GetKeyState = user32.GetKeyState
GetKeyState.argtypes = (ct.c_int,)
GetKeyState.restype = wt.USHORT # !!! It's actually wt.SHORT, but chose unsigned for display purposes !!!
while 1:
vkc = 0x41 # 65, 'A'
ks = GetKeyState(vkc)
print("Key (0x{:02X}) state: 0x{:04X}\nPressed: {:d}".format(vkc, ks, ks >> 15))
time.sleep(0.5)
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
Output:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q069599484]> "e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts\python.exe" code00.py Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] 064bit on win32 Key (0x41) state: 0x0000 Pressed: 0 Key (0x41) state: 0x0000 Pressed: 0 Key (0x41) state: 0x0000 Pressed: 0 Key (0x41) state: 0x0000 Pressed: 0 Key (0x41) state: 0xFF81 Pressed: 1 Key (0x41) state: 0xFF81 Pressed: 1 Key (0x41) state: 0xFF81 Pressed: 1 Key (0x41) state: 0xFF81 Pressed: 1 Key (0x41) state: 0x0001 Pressed: 0 ...