def __iter__(self): """Initialises the message loop and yields all messages until :meth:`stop` is called. :raises AssertionError: if :meth:`start` has not been called """ assert self._threadid is not None try: # Pump messages until WM_STOP while True: msg = wintypes.MSG() lpmsg = ctypes.byref(msg) r = self._GetMessage(lpmsg, None, 0, 0) if r <= 0 or msg.message == self.WM_STOP: break else: yield msg finally: self._threadid = None self.thread = None
def _mainloop(self): """The body of the main loop thread. This method retrieves all events from *Windows* and makes sure to dispatch clicks. """ # Pump messages try: msg = wintypes.MSG() lpmsg = ctypes.byref(msg) while True: r = win32.GetMessage(lpmsg, None, 0, 0) if not r: break elif r == -1: break else: win32.TranslateMessage(lpmsg) win32.DispatchMessage(lpmsg) except: self._log.error('An error occurred in the main loop', exc_info=True) finally: try: self._hide() del self._HWND_TO_ICON[self._hwnd] except: # Ignore pass win32.DestroyWindow(self._hwnd) win32.DestroyWindow(self._menu_hwnd) if self._menu_handle: hmenu, callbacks = self._menu_handle win32.DestroyMenu(hmenu) self._unregister_class(self._atom)
def listenForPaste(funcPress, funcRelease): '''Registers the Ctrl + V hotkey and monitors it untill the thread receives a WM_QUIT message from the main thread. This is the entry point of the monitoring system for the Ctrl + V combination. It registers the hotkey and sends the current thread's ID to the main thread, so we can send a QUIT message from the main to this one when we want to exit. On exit we are checking whether we have a database connection stored on the thread and if we do, we close it. Args: funcPress: A callable to be executed when the hotkey is pressed for more than .15 seconds funcRelease: A callable to be executed when the hotkey is released after being triggered ''' _registerHotkey() t = QThread.currentThread() t.threadId = threading.currentThread().ident try: msg = wintypes.MSG() while u32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0: if msg.message == win32con.WM_HOTKEY: _hold(funcPress, funcRelease) continue if msg.message == win32con.WM_QUIT: break u32.TranslateMessage(ctypes.byref(msg)) u32.DispatchMessageA(ctypes.byref(msg)) finally: u32.UnregisterHotKey(None, 1) logging.info("Unregistered the Ctrl + V hotkey") if hasattr(t, "dbConnection"): getattr(t, "dbConnection").close() logging.info("Closed dbConnection in paste thread")
def hook(self, keyboard=True, mouse=False): """Hook mouse and/or keyboard events""" self.mouse_is_hook = mouse self.keyboard_is_hook = keyboard # check that we are going to hook into at least one device if not self.mouse_is_hook and not self.keyboard_is_hook: raise Exception("You must hook into either the keyboard and/or mouse events") if self.keyboard_is_hook: def keyboard_low_level_handler(code, event_code, kb_data_ptr): """Used to catch keyboard events and deal with the event""" key_code = 0xFFFFFFFF & kb_data_ptr[0] # key code current_key = ID_TO_KEY.get(key_code) # check the type of event (see ID_TO_KEY for a list) if current_key is None: event = None # We can check this later. if self.warn_unrecognised: warn('Unrecognised key ID %d.' % key_code) else: event_type = event_types[0xFFFFFFFF & event_code] if event_type == 'key down': # add key to those down to list if current_key not in self.pressed_keys: self.pressed_keys.append(current_key) if event_type == 'key up': # remove when no longer pressed try: self.pressed_keys.remove(current_key) except ValueError: pass # current_key is not in the list. # wrap the keyboard information grabbed into a container class event = KeyboardEvent(current_key, event_type, self.pressed_keys, key_code) # Call the event handler to deal with keys in the list try: if event: self.handler(event) except Exception as e: warn('While handling {}, self.handler produced a traceback:\n{}'.format(event, format_exc())) finally: # TODO: fix return here to use non-blocking call return CallNextHookEx(self.keyboard_id, code, event_code, kb_data_ptr) keyboard_pointer = _callback_pointer(keyboard_low_level_handler) self.keyboard_id = SetWindowsHookExA(WH_KEYBOARD_LL, keyboard_pointer, GetModuleHandleA(None), 0) if self.mouse_is_hook: def mouse_low_level_handler(code, event_code, kb_data_ptr): """Used to catch and deal with mouse events""" current_key = MOUSE_ID_TO_KEY.get(event_code) # check the type of event (see MOUSE_ID_TO_KEY for a list) if current_key is None: event = None # We can check this later. if self.warn_unrecognised: warn('Unrecognised mouse ID %d.' % event_code) else: if current_key != 'Move': # if we aren't moving, then we deal with a mouse click event_type = MOUSE_ID_TO_EVENT_TYPE[event_code] # the first two members of kb_data_ptr hold the mouse position, x and y event = MouseEvent(current_key, event_type, kb_data_ptr[0], kb_data_ptr[1]) try: if event: self.handler(event) except Exception as e: warn('While handling {}, self.handler produced a traceback:\n{}'.format(event, format_exc())) finally: # TODO: fix return here to use non-blocking call return CallNextHookEx(self.mouse_id, code, event_code, kb_data_ptr) mouse_pointer = _callback_pointer(mouse_low_level_handler) self.mouse_id = SetWindowsHookExA(WH_MOUSE_LL, mouse_pointer, GetModuleHandleA(None), 0) atexit.register(UnhookWindowsHookEx, self.keyboard_id) atexit.register(UnhookWindowsHookEx, self.mouse_id) message = wintypes.MSG() while self.mouse_is_hook or self.keyboard_is_hook: msg = GetMessageW(byref(message), 0, 0, 0) if msg in [0, -1]: self.unhook_keyboard() self.unhook_mouse() break # Exit the loop. else: TranslateMessage(byref(message)) DispatchMessageW(byref(message))
def hook(self, keyboard=True, mouse=False): """Hook mouse and/or keyboard events""" self.mouse_is_hook = mouse self.keyboard_is_hook = keyboard # check that we are going to hook into at least one device if not self.mouse_is_hook and not self.keyboard_is_hook: raise Exception("You must hook into either the keyboard and/or mouse events") if self.keyboard_is_hook: def keyboard_low_level_handler(code, event_code, kb_data_ptr): """Used to catch keyboard events and deal with the event""" try: key_code = 0xFFFFFFFF & kb_data_ptr[0] # key code current_key = ID_TO_KEY[key_code] event_type = event_types[0xFFFFFFFF & event_code] if event_type == 'key down': # add key to those down to list self.pressed_keys.append(current_key) if event_type == 'key up': # remove when no longer pressed self.pressed_keys.remove(current_key) # wrap the keyboard information grabbed into a container class event = KeyboardEvent(current_key, event_type, self.pressed_keys, key_code) # if we have an event handler, call it to deal with keys in the list if self.handler: self.handler(event) finally: # TODO: fix return here to use non-blocking call return CallNextHookEx(self.keyboard_id, code, event_code, kb_data_ptr) keyboard_pointer = _callback_pointer(keyboard_low_level_handler) self.keyboard_id = SetWindowsHookExA(WH_KEYBOARD_LL, keyboard_pointer, GetModuleHandleA(None), 0) if self.mouse_is_hook: def mouse_low_level_handler(code, event_code, kb_data_ptr): """Used to catch and deal with mouse events""" try: current_key = MOUSE_ID_TO_KEY[ event_code] # check the type of event (see MOUSE_ID_TO_KEY for a list) if current_key != 'Move': # if we aren't moving, then we deal with a mouse click event_type = MOUSE_ID_TO_EVENT_TYPE[event_code] # the first two members of kb_data_ptr hold the mouse position, x and y event = MouseEvent(current_key, event_type, kb_data_ptr[0], kb_data_ptr[1]) if self.handler: self.handler(event) finally: # TODO: fix return here to use non-blocking call return CallNextHookEx(self.mouse_id, code, event_code, kb_data_ptr) mouse_pointer = _callback_pointer(mouse_low_level_handler) self.mouse_id = SetWindowsHookExA(WH_MOUSE_LL, mouse_pointer, GetModuleHandleA(None), 0) atexit.register(UnhookWindowsHookEx, self.keyboard_id) atexit.register(UnhookWindowsHookEx, self.mouse_id) message = wintypes.MSG() while self.mouse_is_hook or self.keyboard_is_hook: msg = GetMessageW(byref(message), 0, 0, 0) if msg == -1: self.unhook_keyboard() self.unhook_mouse() exit(0) elif msg == 0: # GetMessage return 0 only if WM_QUIT exit(0) else: TranslateMessage(byref(message)) DispatchMessageW(byref(message))
mll_hook.m_struct.pt.y) # wparam contains the windows message id # if middle mouse button is pressed close the program if wParam == win32con.WM_MBUTTONUP: PostQuitMessage(0) return CallNextHookEx(mll_hook.hook, nCode, wParam, lParam) if __name__ == '__main__': print "Press the middle mouse button to exit " try: mll_hook.hook = SetWindowsHookEx(win32con.WH_MOUSE_LL, LowLevelMouseProc, GetModuleHandle(0), 0) except Exception, err: print err print "got this far..." # set up a message queue, you can use any valid message loop tkinter, pygtk and wxpythons message loops all work #win32gui.PumpMessages() msg = wintypes.MSG() while ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0: print "got message..." ctypes.windll.user32.TranslateMessage(ctypes.byref(msg)) ctypes.windll.user32.DispatchMessageA(ctypes.byref(msg)) print "done?" # unhook the mouse hook UnhookWindowsHookEx(mll_hook.hook)
def listen(connection_to_mom): if connection_to_mom.readable: byref = ctypes.byref user32 = ctypes.windll.user32 keys = connection_to_mom.recv() #dictionary with all possible keys i could find and map to keys on my keyboard (haven't tested all of them though) #this is purely so we can translate human readable keys to the correct Win32Con mapping #there are still Win32con keys available that I haven't used, as I couldn't find those keys on my keyboard, or wasn't sure what the heck it is. keymap = { "enter": win32con.VK_RETURN, "up": win32con.VK_UP, "down": win32con.VK_DOWN, "left": win32con.VK_LEFT, "right": win32con.VK_RIGHT, "backspace": win32con.VK_BACK, "delete": win32con.VK_DELETE, "end": win32con.VK_END, "home": win32con.VK_HOME, "tab": win32con.VK_TAB, "f1": win32con.VK_F1, "f2": win32con.VK_F2, "f3": win32con.VK_F3, "f4": win32con.VK_F4, "f5": win32con.VK_F5, "f6": win32con.VK_F6, "f7": win32con.VK_F7, "f8": win32con.VK_F8, "f9": win32con.VK_F9, "f10": win32con.VK_F10, "f11": win32con.VK_F11, "f12": win32con.VK_F11, "f13": win32con.VK_F13, "f14": win32con.VK_F14, "f15": win32con.VK_F15, "f16": win32con.VK_F16, "f17": win32con.VK_F17, "f18": win32con.VK_F18, "f19": win32con.VK_F19, "f20": win32con.VK_F20, "f21": win32con.VK_F21, "f22": win32con.VK_F22, "f23": win32con.VK_F23, "f24": win32con.VK_F24, "pageup": win32con.VK_PRIOR, "pagedown": win32con.VK_NEXT, "escape": win32con.VK_ESCAPE, "left mouse": win32con.VK_LBUTTON, "right mouse": win32con.VK_RBUTTON, "control break": win32con.VK_CANCEL, "middle mouse": win32con.VK_MBUTTON, "clear": win32con.VK_CLEAR, "shift": win32con.VK_SHIFT, "ctrl": win32con.VK_CONTROL, "menu": win32con.VK_MENU, "pause": win32con.VK_PAUSE, "caps": win32con.VK_CAPITAL, "space": win32con.VK_SPACE, "end": win32con.VK_END, "home": win32con.VK_HOME, "print screen": win32con.VK_SNAPSHOT, "insert": win32con.VK_INSERT, "delete": win32con.VK_DELETE, "windows": win32con.MOD_WIN, "left windows": win32con.VK_LWIN, "right windows": win32con.VK_RWIN, "num0": win32con.VK_NUMPAD0, "num1": win32con.VK_NUMPAD1, "num2": win32con.VK_NUMPAD2, "num3": win32con.VK_NUMPAD3, "num4": win32con.VK_NUMPAD4, "num5": win32con.VK_NUMPAD5, "num6": win32con.VK_NUMPAD6, "num7": win32con.VK_NUMPAD7, "num8": win32con.VK_NUMPAD8, "num9": win32con.VK_NUMPAD9, "*": win32con.VK_MULTIPLY, "+": win32con.VK_ADD, "-": win32con.VK_SUBTRACT, "": win32con.VK_DECIMAL, "/": win32con.VK_DIVIDE, "numlock": win32con.VK_NUMLOCK, "scroll lock": win32con.VK_SCROLL, "left shift": win32con.VK_LSHIFT, "right shift": win32con.VK_RSHIFT, "left ctrl": win32con.VK_LCONTROL, "right ctrl": win32con.VK_RCONTROL, "left menu": win32con.VK_LMENU, "right menu": win32con.VK_RMENU, "mouse wheel": win32con.MOUSEEVENTF_WHEEL, "media mute": win32con.VK_VOLUME_MUTE, "media vol down": win32con.VK_VOLUME_DOWN, "media vol up": win32con.VK_VOLUME_UP, "media next": win32con.VK_MEDIA_NEXT_TRACK, "media prev": win32con.VK_MEDIA_PREV_TRACK, "media play": win32con.VK_MEDIA_PLAY_PAUSE, "prev page": win32con.VK_BROWSER_BACK, "next page": win32con.VK_BROWSER_FORWARD, #dunno what these are, if someone can clarify, I'll maybe add them :), "": win32con.VK_SEPARATOR, "": win32con.VK_KANA, "": win32con.VK_HANGEUL, "": win32con.VK_HANGUL, "": win32con.VK_JUNJA, "": win32con.VK_FINAL, "": win32con.VK_HANJA, "": win32con.VK_KANJI, "": win32con.VK_CONVERT, "": win32con.VK_NONCONVERT, "": win32con.VK_ACCEPT, "": win32con.VK_MODECHANGE, "": win32con.VK_PRIOR, "": win32con.VK_NEXT, "": win32con.VK_SELECT, "": win32con.VK_PRINT, "": win32con.VK_EXECUTE, "": win32con.VK_HELP, "": win32con.VK_APPS, "": win32con.VK_PROCESSKEY, "": win32con.VK_ATTN, "": win32con.VK_CRSEL, "": win32con.VK_EXSEL, "": win32con.VK_EREOF, "": win32con.VK_PLAY, "": win32con.VK_ZOOM, "": win32con.VK_NONAME, "": win32con.VK_PA1, "": win32con.VK_OEM_CLEAR, # multi-media related "": win32con.MOUSEEVENTF_XDOWN, "": win32con.MOUSEEVENTF_XUP, "": win32con.VK_XBUTTON1, "": win32con.VK_XBUTTON2, } #if the user is using custom keys, we have to convert them, as we want to give users an easy option to set their keys, #so they don't need to now the win32con.VKF2 codes and such i = 1 HOTKEYS = {} for key_combo in keys: HOTKEYS[i] = () for key in key_combo: HOTKEYS[i] = HOTKEYS[i] + (keymap[key], ) i += 1 def handle_win_f2(): #sending to parent process that the action, given 1 here, kind of randomly (ID's are better than names) connection_to_mom.send({"action": 1}) def handle_win_f3(): #sending to parent process that the action 2 should be run. connection_to_mom.send({"action": 2}) def handle_win_f4(): #sending to parent process that the action 2 should be run. connection_to_mom.send({"action": 3}) HOTKEY_ACTIONS = {1: handle_win_f2, 2: handle_win_f3, 3: handle_win_f4} # # RegisterHotKey takes: # Window handle for WM_HOTKEY messages (None = this thread) # arbitrary id unique within the thread # modifiers (MOD_SHIFT, MOD_ALT, MOD_CONTROL, MOD_WIN) # VK code (either ord ('x') or one of win32con.VK_*) # for id, (vk, modifiers) in HOTKEYS.items(): #print ("Registering id", id, "for key", vk) if not user32.RegisterHotKey(None, id, modifiers, vk): print("Unable to register id", id) # # Home-grown Windows message loop: does # just enough to handle the WM_HOTKEY # messages and pass everything else along. # try: msg = wintypes.MSG() while user32.GetMessageA(byref(msg), None, 0, 0) != 0: if msg.message == win32con.WM_HOTKEY: action_to_take = HOTKEY_ACTIONS.get(msg.wParam) if action_to_take: action_to_take() user32.TranslateMessage(byref(msg)) user32.DispatchMessageA(byref(msg)) finally: for id in HOTKEYS.keys(): user32.UnregisterHotKey(None, id)
def get_message(): # get pending messages msg = wintypes.MSG() return user32.PeekMessageA(ctypes.pointer(msg), None, 0, 0, PM_REMOVE)
def wait_messages(): # enter message loop msg = wintypes.MSG() while user32.GetMessageA(ctypes.pointer(msg), None, 0, 0): pass
def WaitForMSG(self): msg = wintypes.MSG() self.GetMessage(msg, 0, 0, 0)
def run(self): heartbeat = HeartBeat(self._ppid, self._send_quit) heartbeat.start() import atexit import signal class KBDLLHOOKSTRUCT(ctypes.Structure): _fields_ = [ ("vkCode", wintypes.DWORD), ("scanCode", wintypes.DWORD), ("flags", wintypes.DWORD), ("time", wintypes.DWORD), ("dwExtraInfo", ctypes.c_void_p), ] KeyboardProc = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, wintypes.WPARAM, ctypes.POINTER(KBDLLHOOKSTRUCT)) # Ignore KeyboardInterrupt when attached to a console... signal.signal(signal.SIGINT, signal.SIG_IGN) self._tid = windll.kernel32.GetCurrentThreadId() self._queue.put(self._tid) down_keys = set() passthrough_down_keys = set() def on_key(pressed, event): if (event.flags & 0x10): # Ignore simulated events (e.g. from KeyboardEmulation). return False if event.vkCode in self.PASSTHROUGH_KEYS: if pressed: passthrough_down_keys.add(event.vkCode) else: passthrough_down_keys.discard(event.vkCode) key = SCANCODE_TO_KEY.get(event.scanCode) if key is None: # Unhandled, ignore and don't suppress. return False suppressed = bool(self._suppressed_keys_bitmask[event.scanCode // 64] & (1 << (event.scanCode % 64))) if pressed: if passthrough_down_keys: # Modifier(s) pressed, ignore. return False down_keys.add(key) else: down_keys.discard(key) self._queue.put((key, pressed)) return suppressed hook_id = None def low_level_handler(code, wparam, lparam): if code >= 0: pressed = wparam in (0x100, 0x104) if on_key(pressed, lparam[0]): # Suppressed... return 1 return windll.user32.CallNextHookEx(hook_id, code, wparam, lparam) pointer = KeyboardProc(low_level_handler) hook_id = windll.user32.SetWindowsHookExA( 0x00D, pointer, windll.kernel32.GetModuleHandleW(None), 0) atexit.register(windll.user32.UnhookWindowsHookEx, hook_id) msg = wintypes.MSG() while windll.user32.GetMessageW(ctypes.byref(msg), 0, 0, 0): windll.user32.TranslateMessage(ctypes.byref(msg)) windll.user32.DispatchMessageW(ctypes.byref(msg)) heartbeat.stop()
def low_level_callback(code, rparam, lparam): try: key_code = 0xFFFFFFFF & lparam[0] # key code handler(key_code, rparam) finally: return CallNextHookEx(handle[0], code, rparam, lparam) callback_pointer = CFUNCTYPE(c_int, c_int, wintypes.HINSTANCE, POINTER(c_void_p))(low_level_callback) handle[0] = SetWindowsHookExA(WH_KEYBOARD_LL, callback_pointer, GetModuleHandleA(None), 0) atexit.register(UnhookWindowsHookEx, handle[0]) # Message pumper message = wintypes.MSG() while True: msg = GetMessageW(byref(message), 0, 0, 0) if msg == -1: UnhookWindowsHookEx(handle[0]) sys.exit(0) elif msg == 0: # GetMessage return 0 only if WM_QUIT sys.exit(0) else: TranslateMessage(byref(message)) DispatchMessageW(byref(message)) try: sys.stdin.read() pass finally:
def run(self): global vparams, params, speaking global tid, dll, handle tid = windll.kernel32.GetCurrentThreadId() msg = wintypes.MSG() user32.PeekMessageA(byref(msg), None, 0x400, 0x400, 0) (dll, handle) = eciNew() dll.eciRegisterCallback(handle, callback, None) dll.eciSetOutputBuffer(handle, samples, pointer(buffer)) dll.eciSetParam(handle, 1, 1) self.dictionaryHandle = dll.eciNewDict(handle) dll.eciSetDict(handle, self.dictionaryHandle) #0 = main dictionary if os.path.exists(os.path.join(os.path.dirname(eciPath), "enumain.dic")): dll.eciLoadDict( handle, self.dictionaryHandle, 0, os.path.join(os.path.dirname(eciPath), "enumain.dic").encode('mbcs')) elif os.path.exists(os.path.join(os.path.dirname(eciPath), "main.dic")): dll.eciLoadDict( handle, self.dictionaryHandle, 0, os.path.join(os.path.dirname(eciPath), "main.dic").encode('mbcs')) if os.path.exists(os.path.join(os.path.dirname(eciPath), "enuroot.dic")): dll.eciLoadDict( handle, self.dictionaryHandle, 1, os.path.join(os.path.dirname(eciPath), "enuroot.dic").encode('mbcs')) elif os.path.exists(os.path.join(os.path.dirname(eciPath), "root.dic")): dll.eciLoadDict( handle, self.dictionaryHandle, 1, os.path.join(os.path.dirname(eciPath), "root.dic").encode('mbcs')) if os.path.exists(os.path.join(os.path.dirname(eciPath), "enuabbr.dic")): dll.eciLoadDict( handle, self.dictionaryHandle, 2, os.path.join(os.path.dirname(eciPath), "enuabbr.dic").encode('mbcs')) elif os.path.exists(os.path.join(os.path.dirname(eciPath), "abbr.dic")): dll.eciLoadDict( handle, self.dictionaryHandle, 2, os.path.join(os.path.dirname(eciPath), "abbr.dic").encode('mbcs')) params[9] = dll.eciGetParam(handle, 9) started.set() while True: user32.GetMessageA(byref(msg), 0, 0, 0) user32.TranslateMessage(byref(msg)) if msg.message == WM_PROCESS: internal_process_queue() elif msg.message == WM_SILENCE: speaking = False gb.seek(0) gb.truncate(0) dll.eciStop(handle) try: while True: bgQueue.get_nowait() except: pass player.stop() elif msg.message == WM_PARAM: dll.eciSetParam(handle, msg.lParam, msg.wParam) params[msg.lParam] = msg.wParam param_event.set() elif msg.message == WM_VPARAM: setVParamImpl(param=msg.wParam, val=msg.lParam) param_event.set() elif msg.message == WM_COPYVOICE: dll.eciCopyVoice(handle, msg.wParam, 0) for i in (rate, pitch, vlm, fluctuation, hsz, rgh, bth): vparams[i] = dll.eciGetVoiceParam(handle, 0, i) param_event.set() elif msg.message == WM_KILL: dll.eciDelete(handle) stopped.set() break else: user32.DispatchMessageA(byref(msg))
def wait_for_msg(): msg = wintypes.MSG() GetMessage(msg, 0, 0, 0)
#!/usr/bin/env python3 __version__ = '0.67-beta' __author__ = 'BladeMight' import win32gui as w3g, win32api as w3a, ctypes, atexit import win32clipboard as w3cl from KInputs import * from win32con import * from collections import namedtuple from ctypes import wintypes, windll, CFUNCTYPE, POINTER, c_int, c_void_p from time import sleep import Locales as lcs from ToUn import * # Hotkeys & functions related to it brf = ctypes.byref u32 = ctypes.windll.user32 m = wintypes.MSG() def HKHandle(ID): global self print("HK with id = {} fired.".format(ID)) if ID == 0: '''Converts selection''' # Below needed for AllList to return correct next locale id. w3a.PostMessage(w3g.GetForegroundWindow(), 0x50, lcs.GetNotCurrentLocale()) ConvertSelection() print(self) if ID == 1 and not self: '''Converts typed last word''' ConvertLast(c_word)