模拟程序
# direct inputs
# source to this solution and code:
# http://stackoverflow.com/questions/14489013/simulate-python-keypresses-for-controlling-a-game
# http://www.gamespp.com/directx/directInputKeyboardScanCodes.html
import ctypes
import time
SendInput = ctypes.windll.user32.SendInput
W = 0x11
A = 0x1E
S = 0x1F
D = 0x20
Z = 0x2c
X = 0x2d
G = 0x22
NP_2 = 0x50
NP_4 = 0x4B
NP_6 = 0x4D
NP_8 = 0x48
# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]
class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time",ctypes.c_ulong),
("dwExtraInfo", PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]
# Actuals Functions
def PressKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
if __name__ == '__main__':
PressKey(0x11)
time.sleep(1)
ReleaseKey(0x11)
time.sleep(1)
案例:
通过串口控制键盘输入
import serial
import time
from directkeys import ReleaseKey,PressKey,Z,X,G
ser = serial.Serial('COM5', 115200,timeout=0.01 )#,parity=serial.PARITY_EVEN, rtscts=1
ser.close()
ser.open()
a = (6,5,4,3,2,1)
for i in a:
time.sleep(1)
print(i)
while True:
s = ser.read(3)
if len(s)>2:
ss = s
print(ss)
if ss[0] == 49:
ReleaseKey(Z)
#print("W松开")
if ss[0] == 48:
PressKey(Z)
#print("W按下")
if ss[1] == 49:
ReleaseKey(X)
#print("X松开")
if ss[1] == 48:
PressKey(X)
#print("X按下")
if ss[2] == 49:
ReleaseKey(G)
#print("G松开")
if ss[2] == 48:
PressKey(G)
#print("G按下")
附录:
键盘码https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
Ordinary scancodes
The scancodes in translated scancode set 2 are given in hex. Between parentheses the keycap on a US keyboard. The scancodes are given in order, grouped according to groups of keys that are usually found next to each other.
00 is normally an error code
01 (Esc)
02 (1!), 03 (2@), 04 (3#), 05 (4$), 06 (5%E), 07 (6^), 08 (7&), 09 (8*), 0a (9(), 0b (0)), 0c (-_), 0d (=+), 0e (Backspace)
0f (Tab), 10 (Q), 11 (W), 12 (E), 13 ®, 14 (T), 15 (Y), 16 (U), 17 (I), 18 (O), 19 §, 1a ([{), 1b (]})
1c (Enter)
1d (LCtrl)
1e (A), 1f (S), 20 (D), 21 (F), 22 (G), 23 (H), 24 (J), 25 (K), 26 (L), 27 ( : ; ), 28 (’ ") 29 (` ~)
2a (LShift)
2b (|), on a 102-key keyboard
2c (Z), 2d (X), 2e ©, 2f (V), 30 (B), 31 (N), 32 (M), 33 (,<), 34 (.>), 35 (/?), 36 (RShift)
37 (Keypad-) or (/PrtScn) on a 83/84-key keyboard
38 (LAlt), 39 (Space bar),
3a (CapsLock)
3b (F1), 3c (F2), 3d (F3), 3e (F4), 3f (F5), 40 (F6), 41 (F7), 42 (F8), 43 (F9), 44 (F10)
45 (NumLock)
46 (ScrollLock)
47 (Keypad-7/Home), 48 (Keypad-8/Up), 49 (Keypad-9/PgUp)
4a (Keypad–)
4b (Keypad-4/Left), 4c (Keypad-5), 4d (Keypad-6/Right), 4e (Keypad-+)
4f (Keypad-1/End), 50 (Keypad-2/Down), 51 (Keypad-3/PgDn)
52 (Keypad-0/Ins), 53 (Keypad-./Del)
54 (Alt-SysRq) on a 84+ key keyboard
55 is less common; occurs e.g. as F11 on a Cherry G80-0777 keyboard, as F12 on a Telerate keyboard, as PF1 on a Focus 9000 keyboard, and as FN on an IBM ThinkPad.
56 mostly on non-US keyboards. It is often an unlabelled key to the left or to the right of the left Alt key.
57 (F11), 58 (F12) both on a 101+ key keyboard
59-5a-…-7f are less common. Assignment is essentially random. Scancodes 55-59 occur as F11-F15 on the Cherry G80-0777 keyboard. Scancodes 59-5c occur on the RC930 keyboard. X calls 5d `KEY_Begin’. Scancodes 61-64 occur on a Telerate keyboard. Scancodes 55, 6d, 6f, 73, 74, 77, 78, 79, 7a, 7b, 7c, 7e occur on the Focus 9000 keyboard. Scancodes 65, 67, 69, 6b occur on a Compaq Armada keyboard. Scancodes 66-68, 73 occur on the Cherry G81-3000 keyboard. Scancodes 70, 73, 79, 7b, 7d occur on a Japanese 86/106 keyboard.
Scancodes f1 and f2 occur on Korean keyboards.