Catching keystrokes under Windows

Richie Hindle richie at entrian.com
Thu Nov 20 17:25:16 CET 2003


[Olli]
> I'm having a little problem catching keystrokes under Windows.
> [...] when the program is being run on the background.

[Mike]
> To do this for all Windows applications, you need to use a systemwide
> message hook, which is set with the Windows function SetWindowsHookEx
> using the WH_KEYBOARD option.

There's an easier way using Windows Hotkeys, as long as you don't expect
the keystroke to be delivered to the focussed application (eg. if the
feature is something like "Press Ctrl+Shift+S to shut down the reactor").

---------------------------------------------------------------------

import sys
from ctypes import *
from ctypes.wintypes import *

# Define the Windows DLLs, constants and types that we need.
user32 = windll.user32

WM_HOTKEY   = 0x0312
MOD_ALT     = 0x0001
MOD_CONTROL = 0x0002
MOD_SHIFT   = 0x0004

class MSG(Structure):
    _fields_ = [('hwnd', c_int),
                ('message', c_uint),
                ('wParam', c_int),
                ('lParam', c_int),
                ('time', c_int),
                ('pt', POINT)]

# Register a hotkey for Ctrl+Shift+S.
hotkeyId = 1
if not user32.RegisterHotKey(None, hotkeyId, MOD_CONTROL | MOD_SHIFT, ord('S')):
    sys.exit("Failed to register hotkey; maybe someone else registered it?")

# Spin a message loop waiting for WM_HOTKEY.
msg = MSG()
while user32.GetMessageA(byref(msg), None, 0, 0) != 0:
    if msg.message == WM_HOTKEY and msg.wParam == hotkeyId:
        print "Yay!"
        windll.user32.PostQuitMessage(0)
    user32.TranslateMessage(byref(msg))
    user32.DispatchMessageA(byref(msg))

---------------------------------------------------------------------

-- 
Richie Hindle
richie at entrian.com






More information about the Python-list mailing list