Source code for ahkpy.window_message
import dataclasses as dc
import functools
from typing import Callable
from .flow import ahk_call, _wrap_callback
__all__ = [
"MessageHandler",
"on_message",
]
[docs]def on_message(msg_number: int, func=None, *args, max_threads=1, prepend_handler=False):
"""Register *func* to be called on window message *msg_number*.
Upon receiving a window message, the *func* will be called with the
following arguments:
:param int w_param: the message's *wParam* value
:param int l_param: the message's *lParam* value
:param int msg: the message number, which is useful in cases where a
function monitors more than one message
:param int hwnd: the HWND (unique ID) of the window or control to which the
message was sent
The optional positional *args* will be passed to the *func* when it is
called. If you want the callback to be called with keyword arguments use
:func:`functools.partial`.
The optional *max_threads* argument sets the number of messages AHK can
handle concurrently.
If the optional *prepend_handler* argument is set to ``True``, the *func*
will be registered to be called before any other functions previously
registered for *msg_number*.
If *func* is given, returns an instance of :class:`MessageHandler`.
Otherwise, the function works as a decorator::
WM_CLOSE = 0x0010
@ahkpy.on_message(WM_CLOSE)
def handler(w_param, l_param, msg, hwnd):
print("was asked to close")
assert isinstance(handler, ahkpy.MessageHandler)
:command: `OnMessage
<https://www.autohotkey.com/docs/commands/OnMessage.htm>`_
"""
if max_threads is not None and max_threads <= 0:
raise ValueError("max_threads must be positive")
if prepend_handler:
max_threads *= -1
def on_message_decorator(func):
func = _wrap_callback(
functools.partial(func, *args),
("w_param", "l_param", "msg", "hwnd"),
_bare_message_handler,
_message_handler,
)
ahk_call("OnMessage", int(msg_number), func, max_threads)
return MessageHandler(msg_number, func)
if func is None:
return on_message_decorator
return on_message_decorator(func)
def _bare_message_handler(func, *_):
return func()
def _message_handler(func, w_param, l_param, msg, hwnd):
return func(w_param=w_param, l_param=l_param, msg=msg, hwnd=hwnd)
[docs]@dc.dataclass(frozen=True)
class MessageHandler:
"""This immutable object holds a function registered to be called upon
receiving a window message.
Creating an instance of :class:`!MessageHandler` doesn't register the
function as a handler. Use the :func:`on_message` function instead.
"""
# There's no point in making MessageHandler mutable like the Timer. It's
# complicated and doesn't add any usability points.
msg_number: int
func: Callable
__slots__ = ("msg_number", "func")
[docs] def unregister(self):
"""Unregister the message handler."""
ahk_call("OnMessage", self.msg_number, self.func, 0)