因為特殊需要, 想找一套能簡單發送鍵盤訊息,類比鍵盤操作的模組。 類似於 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 - 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 = keyCode100 inputs[1].ui.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP101 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 cC112 else:113 if vk < 0:114 vk = ~vk + 0x1115 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 shift119 KeyPress(vk & 0xFF , shift)120 else:121 UniKeyPress(cC)122 #print cC123 124 125 126 127 128 129 130 if __name__ == '__main__':131 pass;