Created
July 17, 2012 15:15
-
-
Save fabrixxm/3130003 to your computer and use it in GitHub Desktop.
Windows global hotkeys in a thread
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# After "Tim Golden's Python Stuff" code | |
# http://timgolden.me.uk/python/win32_how_do_i/catch_system_wide_hotkeys.html | |
# | |
# After a post to c.l.py by Richie Hindle: | |
# http://groups.google.com/groups?th=80e876b88fabf6c9 | |
# | |
import os | |
import sys | |
import threading | |
import ctypes | |
from ctypes import wintypes | |
import win32con | |
byref = ctypes.byref | |
user32 = ctypes.windll.user32 | |
HOTKEYS = { | |
1 : (win32con.VK_F1, None), | |
} | |
def handle_default(key): | |
print "* handle key", key | |
user32.PostQuitMessage (0) | |
HOTKEY_ACTIONS = { | |
1 : handle_default, | |
} | |
class GlobalKeys(threading.Thread): | |
def __init__(self, hotkeys=HOTKEYS, actions=HOTKEY_ACTIONS): | |
"""HOTKEYS: dict{ id: (key, modifier) } | |
HOTKEY_ACTIONS: dict{ id: callback }""" | |
super(GlobalKeys, self).__init__() | |
self.HOTKEYS = hotkeys | |
self.HOTKEY_ACTIONS = actions | |
self.loop = True | |
self.HOTKEYS[0] = (None, None) | |
self.HOTKEY_ACTIONS[0] = handle_default | |
def run(self): | |
# | |
# 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 self.HOTKEYS.items (): | |
#print "Registering id", id, "for key", vk | |
if not user32.RegisterHotKey (None, id, modifiers, vk): | |
print "Unable to register hotkey 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 = self.HOTKEY_ACTIONS.get (msg.wParam) | |
if action_to_take: | |
action_to_take(msg.wParam) | |
user32.TranslateMessage (byref (msg)) | |
user32.DispatchMessageA (byref (msg)) | |
if not self.loop: | |
break | |
finally: | |
for id in self.HOTKEYS.keys (): | |
user32.UnregisterHotKey (None, id) | |
def stop(self): | |
self.loop = False | |
user32.keybd_event(None, 0, 0, 0) | |
user32.keybd_event(None, 0, 0x0002, 0) | |
if __name__=="__main__": | |
gk = GlobalKeys() | |
print "start" | |
gk.start() | |
print "running" | |
gk.join() | |
print "end" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment