import ctypes from ctypes import WinDLL, byref, WinError from ctypes.wintypes import MSG _user32 = WinDLL("user32") GetMessage = _user32.GetMessageA GetMessage.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint, ctypes.c_uint, ] TranslateMessage = _user32.TranslateMessage DispatchMessage = _user32.DispatchMessageA class _MessageLoop(object): def __init__(self): self._filters = [] def insert_filter(self, obj, index=-1): self._filters.insert(index, obj) def remove_filter(self, obj): self._filters.remove(obj) def run(self): msg = MSG() lpmsg = byref(msg) while 1: ret = GetMessage(lpmsg, 0, 0, 0) if ret == -1: raise WinError() elif ret == 0: return # got WM_QUIT if not self.filter_message(lpmsg): TranslateMessage(lpmsg) DispatchMessage(lpmsg) def filter_message(self, lpmsg): return any(list(filter(lpmsg)) for filter in self._filters) _messageloop = _MessageLoop() run = _messageloop.run insert_filter = _messageloop.insert_filter remove_filter = _messageloop.remove_filter __all__ = ["run", "insert_filter", "remove_filter"]