def SendRawCodes2(self, keyData, hwnd, mode): """ Uses PostMessage and SetKeyboardState to emulate the the virtual keycode. Can send to a specified window handle. """ keyboardStateBuffer = self.keyboardStateBuffer for block in keyData: if mode == 1 or mode == 2: for virtualKey in block: keyCode = virtualKey & 0xFF highBits = virtualKey & 0xFF00 lparam = ((MapVirtualKey(keyCode, 0) | highBits) << 16) | 1 keyboardStateBuffer[keyCode] |= 128 if keyCode == VK_LSHIFT: keyboardStateBuffer[VK_SHIFT] |= 128 #elif keyCode == VK_MENU: # self.isSysKey = True elif keyCode == VK_CONTROL: keyboardStateBuffer[VK_LCONTROL] |= 128 if self.isSysKey: mesg = WM_SYSKEYDOWN lparam |= 0x20000000 else: mesg = WM_KEYDOWN SetKeyboardState(byref(keyboardStateBuffer)) PostMessage(hwnd, mesg, keyCode, lparam) self.WaitForInputProcessed() if mode == 0 or mode == 2: for virtualKey in reversed(block): keyCode = virtualKey & 0xFF highBits = virtualKey & 0xFF00 lparam = ( ((MapVirtualKey(keyCode, 0) | highBits) << 16) | 0xC0000001 ) keyboardStateBuffer[keyCode] &= ~128 if keyCode == VK_LSHIFT: keyboardStateBuffer[VK_SHIFT] &= ~128 #elif keyCode == VK_MENU: # self.isSysKey = False elif keyCode == VK_CONTROL: keyboardStateBuffer[VK_LCONTROL] &= ~128 if self.isSysKey: mesg = WM_SYSKEYUP lparam |= 0x20000000 else: mesg = WM_KEYUP SetKeyboardState(byref(keyboardStateBuffer)) PostMessage(hwnd, mesg, keyCode, lparam) self.WaitForInputProcessed()
def __call__(self, hwnd, keystrokeString, useAlternateMethod=False, mode=2): keyData = ParseText(keystrokeString) if keyData: needGetFocus = False sendToFront = False if hwnd is None: sendToFront = True hwnd = GetForegroundWindow() needGetFocus = True dwProcessId = DWORD() threadID = GetWindowThreadProcessId(hwnd, byref(dwProcessId)) processID = dwProcessId.value ourThreadID = GetCurrentThreadId() # If not, attach our thread's 'input' to the foreground thread's if threadID != ourThreadID: AttachThreadInput(threadID, ourThreadID, True) if needGetFocus: hwnd = GetFocus() if not sendToFront: if GetGUIThreadInfo(0, byref(self.guiTreadInfo)): sendToFront = (self.guiTreadInfo.hwndFocus == hwnd) else: sendToFront = False if not hwnd: hwnd = None self.procHandle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, processID) #self.WaitForInputProcessed() oldKeyboardState = PBYTE256() GetKeyboardState(byref(oldKeyboardState)) keyData = ParseText(keystrokeString) if sendToFront and not useAlternateMethod: self.SendRawCodes1(keyData, mode) else: self.SendRawCodes2(keyData, hwnd, mode) SetKeyboardState(byref(oldKeyboardState)) self.WaitForInputProcessed() if threadID != ourThreadID: AttachThreadInput(threadID, ourThreadID, False) if self.procHandle: CloseHandle(self.procHandle)