因为特殊需要, 想找一套能简单发送键盘消息,模拟键盘操作的模块。 类似于 C#.net 或 VB 的 sendKeys 函数。
找了很久没有合适的。 参考了一些网上的资料,使用windows API SendInput 自已重新写了一个。
SendKeys2.py
代码语言:javascript复制 1 #!/usr/bin/python
2 # -*- coding: gbk -*-
3
4 # SendKeys2.py
5 #
6 # Copyright (C) 2012 - xulong <fangkailove@gmail.com>
7 #
8 from ctypes import *
9 import time
10 import win32con
11 import win32api
12 import win32ui
13
14 #Structure for a keycode input
15 class KeyBdInput(Structure):
16 _fields_ = [
17 ("wVk",c_ushort),
18 ("wScan",c_ushort),
19 ("dwFlags",c_ulong),
20 ("time",c_ulong),
21 ("dwExtraInfo",POINTER(c_ulong))
22 ]
23 #dwFlags can be certain combinations of the following values
24 KEYEVENTF_EXTENDEDKEY = 0x0001 #If specified, the scan code was preceded by a prefix byte that has the value 0xE0 (224).
25 KEYEVENTF_KEYUP = 0x0002 #If specified, the key is being released. If not specified, #the key is being pressed.
26 KEYEVENTF_SCANCODE = 0x0008 #If specified, wScan identifies the key and wVk is ignored.
27 KEYEVENTF_UNICODE = 0x0004 #If specified, the system synthesizes a VK_PACKET keystroke. The wVk parameter must be zero. This flag can only be combined with the KEYEVENTF_KEYUP flag.
28
29
30 #remark:
31 #dwFalgs default set 0 .
32 #when 1 >= keycode <= 254 set wVk = keycode and set wScan = 0
33 #when keycode>254(unicode) set wScan = keycode and set wVk = 0
34 # and set dwFlags |= KEYEVENTF_UNICODE
35 #
36 class HardwareInput(Structure):
37 _fields_ = [("uMsg", c_ulong),("wParamL", c_short),("wParamH", c_ushort)]
38
39 class MouseInput(Structure):
40 _fields_ = [("dx", c_long),("dy", c_long),("mouseData", c_ulong),("dwFlags", c_ulong),("time",c_ulong),("dwExtraInfo", POINTER(c_ulong))]
41
42 class Union_Input(Union):
43 _fields_ = [("ki", KeyBdInput),("mi", MouseInput),("hi", HardwareInput)]
44
45 class Input(Structure):
46 _fields_=[
47 ("type",c_ulong),
48 ("ui",Union_Input)
49 ]
50 #type can be one of the following value
51 INPUT_MOUSE = 0 #The event is a mouse event. Use the mi structure of the union.
52 INPUT_KEYBOARD = 1 #The event is a keyboard event. Use the ki structure of the union.
53 INPUT_HARDWARE = 2 #The event is a hardware event. Use the hi structure of the union.
54
55
56
57
58 def send_key_event(keyCode,isKeyup):
59
60 Inputs = Input * 1
61 inputs = Inputs()
62
63 inputs[0].type = INPUT_KEYBOARD
64 inputs[0].ui.ki.wVk = keyCode
65 if isKeyup == True:
66 inputs[0].ui.ki.dwFlags = KEYEVENTF_KEYUP
67 windll.user32.SendInput(1, pointer(inputs), sizeof(inputs[0]))
68 win32api.Sleep(3)
69
70 def KeyDown(keyCode):
71 send_key_event(keyCode,False)
72
73 def KeyUp(keyCode):
74 send_key_event(keyCode,True)
75
76
77 #char in 1~255 key press
78 def KeyPress(keyCode,isShift):
79 if isShift == True:
80 send_key_event(win32con.VK_SHIFT,False)
81 send_key_event(keyCode,False)
82 send_key_event(keyCode,True)
83 if isShift == True:
84 send_key_event(win32con.VK_SHIFT,True)
85
86
87 #unicode char key press
88 def UniKeyPress(keyCode):
89 Inputs = Input * 2
90 inputs = Inputs()
91
92 inputs[0].type = INPUT_KEYBOARD
93 inputs[0].ui.ki.wVk = 0
94 inputs[0].ui.ki.wScan = keyCode
95 inputs[0].ui.ki.dwFlags = KEYEVENTF_UNICODE
96
97 inputs[1].type = INPUT_KEYBOARD
98 inputs[1].ui.ki.wVk = 0
99 inputs[1].ui.ki.wScan = keyCode
100 inputs[1].ui.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP
101 windll.user32.SendInput(2, pointer(inputs), sizeof(inputs[0]))
102 win32api.Sleep(5)
103
104 def SendString(Keys):
105 for c in Keys:
106 cC = ord(c)
107 if cC>=0 and cC<256:
108 vk = win32api.VkKeyScan(c)
109 if vk == -1:
110 UniKeyPress(cC)
111 #print cC
112 else:
113 if vk < 0:
114 vk = ~vk 0x1
115 shift = ( vk >> 8 & 0x1 == 0x1 )
116 if win32api.GetKeyState(win32con.VK_CAPITAL) & 0x1 == 0x1:
117 if ( c >= 'a' and c <= 'z' ) or ( c >= 'A' and c <= 'Z' ):
118 shift = not shift
119 KeyPress(vk & 0xFF , shift)
120 else:
121 UniKeyPress(cC)
122 #print cC
123
124
125
126
127
128
129
130 if __name__ == '__main__':
131 pass;