ctypes.windll.user32.GetKeyState 无法识别按键
ctypes.windll.user32.GetKeyState not recognizing key presses
我遇到一个问题,ctypes.windll.user32.GetKeyState 无法检测到我键盘上的按键(A、B、C、e.t.c),但它确实检测到左键和鼠标右键。
我正在尝试制作一个简单的脚本来检测小写的“a”键。我通过 ord('a')
.
得到了数字 97
import ctypes
def a_pressed():
return ctypes.windll.user32.GetKeyState(97) > 1
while True:
if a_pressed():
print('a is pressed')
我是做错了什么,还是我不知道 API 的某些限制?
[MS.Docs]: GetKeyState function (winuser.h)(重点是我的):
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.
“有点”误导。
来自ASCII的PoV,有明显区别(例如):
- a: 0x61 (97)
- A: 0x41 (65)
从键盘的 PoV,情况有点不同(当按下一个键时):
- a:第3行行第2nd列的键,位于CapsLock 的右侧(在 US 键盘上)
- A:同上,但有:
- 大写锁定开
- Shift 也按下
[MS.Docs]: Virtual-Key Codes 说清楚了:为了检查 A(或 a)的状态,0x41 (65)必须勾选(97对应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)
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\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
...
如何使用函数的示例:
def is_key_pressed(virtual_key_code):
return bool(GetKeyState(virtual_key_code) >> 15)
# Examples
is_key_pressed(ord("A")) # A (a)
is_key_pressed(0x1B) # Esc
我遇到一个问题,ctypes.windll.user32.GetKeyState 无法检测到我键盘上的按键(A、B、C、e.t.c),但它确实检测到左键和鼠标右键。
我正在尝试制作一个简单的脚本来检测小写的“a”键。我通过 ord('a')
.
import ctypes
def a_pressed():
return ctypes.windll.user32.GetKeyState(97) > 1
while True:
if a_pressed():
print('a is pressed')
我是做错了什么,还是我不知道 API 的某些限制?
[MS.Docs]: GetKeyState function (winuser.h)(重点是我的):
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.
“有点”误导。
来自ASCII的PoV,有明显区别(例如):
- a: 0x61 (97)
- A: 0x41 (65)
从键盘的 PoV,情况有点不同(当按下一个键时):
- a:第3行行第2nd列的键,位于CapsLock 的右侧(在 US 键盘上)
- A:同上,但有:
- 大写锁定开
- Shift 也按下
[MS.Docs]: Virtual-Key Codes 说清楚了:为了检查 A(或 a)的状态,0x41 (65)必须勾选(97对应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)
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\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 ...
如何使用函数的示例:
def is_key_pressed(virtual_key_code):
return bool(GetKeyState(virtual_key_code) >> 15)
# Examples
is_key_pressed(ord("A")) # A (a)
is_key_pressed(0x1B) # Esc