Skip to content

Instantly share code, notes, and snippets.

@fabrixxm
Created July 17, 2012 15:15
Show Gist options
  • Save fabrixxm/3130003 to your computer and use it in GitHub Desktop.
Save fabrixxm/3130003 to your computer and use it in GitHub Desktop.
Windows global hotkeys in a thread
# 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