因为特殊需要, 想找一套能简单发送键盘消息,模拟键盘操作的模块。 类似于 C#.net 或 VB 的 sendKeys 函数。
找了很久没有合适的。 参考了一些网上的资料,使用windows API SendInput 自已重新写了一个。
SendKeys2.py
1 #!/usr/bin/python 2 # -*- coding: gbk -*- 3 4 # SendKeys2.py 5 # 6 # Copyright (C) 2012 - xulong7 # 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;