From 6260ad33469e0a8a33dc55acd2939ccc57dfc6ee Mon Sep 17 00:00:00 2001 From: junkmd Date: Sat, 7 Mar 2026 13:01:13 +0900 Subject: [PATCH 1/7] refactor: Eliminates the alias `LRESULT = LPLONG` by directly importing `LPLONG` as `LRESULT` from `ctypes.wintypes`. --- comtypes/test/test_eventinterface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/comtypes/test/test_eventinterface.py b/comtypes/test/test_eventinterface.py index f2b9d303..f581cf5e 100644 --- a/comtypes/test/test_eventinterface.py +++ b/comtypes/test/test_eventinterface.py @@ -1,6 +1,7 @@ import unittest as ut from ctypes import POINTER, Structure, WinDLL, byref, c_long, c_uint, c_ulong -from ctypes.wintypes import BOOL, HWND, LPLONG, UINT +from ctypes.wintypes import BOOL, HWND, UINT +from ctypes.wintypes import LPLONG as LRESULT from comtypes.client import CreateObject, GetEvents @@ -68,7 +69,6 @@ def PumpWaitingMessages(): _TranslateMessage.argtypes = [POINTER(MSG)] _TranslateMessage.restype = BOOL - LRESULT = LPLONG _DispatchMessageA = _user32.DispatchMessageA _DispatchMessageA.argtypes = [POINTER(MSG)] _DispatchMessageA.restype = LRESULT From 49ceff798dd5ee5cb6ed6b50f13f37d772a2543e Mon Sep 17 00:00:00 2001 From: junkmd Date: Sat, 7 Mar 2026 13:01:13 +0900 Subject: [PATCH 2/7] refactor: Streamline `test_eventinterface.py` imports by using `ctypes.wintypes.MSG` - Removes redundant `POINT` and `MSG` structure definitions. - Directly imports `MSG` from `ctypes.wintypes`, simplifying the import statements. - Reduces boilerplate code and improves consistency by leveraging standard `wintypes` definitions. --- comtypes/test/test_eventinterface.py | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/comtypes/test/test_eventinterface.py b/comtypes/test/test_eventinterface.py index f581cf5e..e61207c0 100644 --- a/comtypes/test/test_eventinterface.py +++ b/comtypes/test/test_eventinterface.py @@ -1,6 +1,6 @@ import unittest as ut -from ctypes import POINTER, Structure, WinDLL, byref, c_long, c_uint, c_ulong -from ctypes.wintypes import BOOL, HWND, UINT +from ctypes import POINTER, WinDLL, byref +from ctypes.wintypes import BOOL, HWND, MSG, UINT from ctypes.wintypes import LPLONG as LRESULT from comtypes.client import CreateObject, GetEvents @@ -43,21 +43,6 @@ def DocumentComplete(self, this, *args): self._events.append("DocumentComplete") -class POINT(Structure): - _fields_ = [("x", c_long), ("y", c_long)] - - -class MSG(Structure): - _fields_ = [ - ("hWnd", c_ulong), - ("message", c_uint), - ("wParam", c_ulong), - ("lParam", c_ulong), - ("time", c_ulong), - ("pt", POINT), - ] - - def PumpWaitingMessages(): _user32 = WinDLL("user32") From c93e447de7312cc39689f9c5797d5bd3251c8392 Mon Sep 17 00:00:00 2001 From: junkmd Date: Sat, 7 Mar 2026 13:01:13 +0900 Subject: [PATCH 3/7] refactor: Explicitly define WinAPI function signatures in `messageloop.py`. - Adds `argtypes` and `restype` for `GetMessage`, `TranslateMessage`, and `DispatchMessage`. --- comtypes/messageloop.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/comtypes/messageloop.py b/comtypes/messageloop.py index 27b67068..a2c2fa22 100644 --- a/comtypes/messageloop.py +++ b/comtypes/messageloop.py @@ -1,6 +1,7 @@ import ctypes from ctypes import WinDLL, WinError, byref -from ctypes.wintypes import MSG +from ctypes.wintypes import BOOL, MSG +from ctypes.wintypes import LPLONG as LRESULT from typing import TYPE_CHECKING, SupportsIndex if TYPE_CHECKING: @@ -14,8 +15,15 @@ GetMessage = _user32.GetMessageA GetMessage.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint, ctypes.c_uint] +GetMessage.restype = BOOL + TranslateMessage = _user32.TranslateMessage +TranslateMessage.argtypes = [ctypes.c_void_p] +TranslateMessage.restype = BOOL + DispatchMessage = _user32.DispatchMessageA +DispatchMessage.argtypes = [ctypes.c_void_p] +DispatchMessage.restype = LRESULT class _MessageLoop: From 4d0b45ab84e4d8a5b38f28b9d74a2df635fd66fb Mon Sep 17 00:00:00 2001 From: junkmd Date: Sat, 7 Mar 2026 13:01:14 +0900 Subject: [PATCH 4/7] refactor: Use `POINTER(MSG)` for message function `argtypes` in `messageloop.py` --- comtypes/messageloop.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/comtypes/messageloop.py b/comtypes/messageloop.py index a2c2fa22..29ccaa3b 100644 --- a/comtypes/messageloop.py +++ b/comtypes/messageloop.py @@ -1,5 +1,5 @@ import ctypes -from ctypes import WinDLL, WinError, byref +from ctypes import POINTER, WinDLL, WinError, byref from ctypes.wintypes import BOOL, MSG from ctypes.wintypes import LPLONG as LRESULT from typing import TYPE_CHECKING, SupportsIndex @@ -14,15 +14,15 @@ _user32 = WinDLL("user32") GetMessage = _user32.GetMessageA -GetMessage.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint, ctypes.c_uint] +GetMessage.argtypes = [POINTER(MSG), ctypes.c_void_p, ctypes.c_uint, ctypes.c_uint] GetMessage.restype = BOOL TranslateMessage = _user32.TranslateMessage -TranslateMessage.argtypes = [ctypes.c_void_p] +TranslateMessage.argtypes = [POINTER(MSG)] TranslateMessage.restype = BOOL DispatchMessage = _user32.DispatchMessageA -DispatchMessage.argtypes = [ctypes.c_void_p] +DispatchMessage.argtypes = [POINTER(MSG)] DispatchMessage.restype = LRESULT From 239d970bef4eaab04e8b0e5014cb036f9207095a Mon Sep 17 00:00:00 2001 From: junkmd Date: Sat, 7 Mar 2026 13:01:14 +0900 Subject: [PATCH 5/7] refactor: Use `HWND` for window handle in `GetMessage` argtypes in `messageloop.py` --- comtypes/messageloop.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/comtypes/messageloop.py b/comtypes/messageloop.py index 29ccaa3b..860d5ae7 100644 --- a/comtypes/messageloop.py +++ b/comtypes/messageloop.py @@ -1,6 +1,6 @@ import ctypes from ctypes import POINTER, WinDLL, WinError, byref -from ctypes.wintypes import BOOL, MSG +from ctypes.wintypes import BOOL, HWND, MSG from ctypes.wintypes import LPLONG as LRESULT from typing import TYPE_CHECKING, SupportsIndex @@ -14,7 +14,7 @@ _user32 = WinDLL("user32") GetMessage = _user32.GetMessageA -GetMessage.argtypes = [POINTER(MSG), ctypes.c_void_p, ctypes.c_uint, ctypes.c_uint] +GetMessage.argtypes = [POINTER(MSG), HWND, ctypes.c_uint, ctypes.c_uint] GetMessage.restype = BOOL TranslateMessage = _user32.TranslateMessage From f31c45060a3128a173df994db016f74e0b9fcec4 Mon Sep 17 00:00:00 2001 From: junkmd Date: Sat, 7 Mar 2026 13:01:14 +0900 Subject: [PATCH 6/7] refactor: Centralize `PeekMessage` in `messageloop.py` and reuse in tests. - Define `PeekMessage` with `argtypes` and `restype` in `messageloop.py`. - Update `test_eventinterface.py` and `test_git.py` to use `PeekMessage` and others from `messageloop`, removing redundant WinAPI definitions. --- comtypes/messageloop.py | 5 +++++ comtypes/test/test_eventinterface.py | 26 ++++++-------------------- comtypes/test/test_git.py | 9 ++------- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/comtypes/messageloop.py b/comtypes/messageloop.py index 860d5ae7..970e2ba5 100644 --- a/comtypes/messageloop.py +++ b/comtypes/messageloop.py @@ -25,6 +25,11 @@ DispatchMessage.argtypes = [POINTER(MSG)] DispatchMessage.restype = LRESULT +# https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-peekmessagea +PeekMessage = _user32.PeekMessageA +PeekMessage.argtypes = [POINTER(MSG), HWND, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint] +PeekMessage.restype = BOOL + class _MessageLoop: def __init__(self) -> None: diff --git a/comtypes/test/test_eventinterface.py b/comtypes/test/test_eventinterface.py index e61207c0..c7d8c6b2 100644 --- a/comtypes/test/test_eventinterface.py +++ b/comtypes/test/test_eventinterface.py @@ -1,9 +1,9 @@ import unittest as ut -from ctypes import POINTER, WinDLL, byref -from ctypes.wintypes import BOOL, HWND, MSG, UINT -from ctypes.wintypes import LPLONG as LRESULT +from ctypes import byref +from ctypes.wintypes import MSG from comtypes.client import CreateObject, GetEvents +from comtypes.messageloop import DispatchMessage, PeekMessage, TranslateMessage # FIXME: External test dependencies like this seem bad. Find a different # built-in win32 API to use. @@ -44,25 +44,11 @@ def DocumentComplete(self, this, *args): def PumpWaitingMessages(): - _user32 = WinDLL("user32") - - _PeekMessageA = _user32.PeekMessageA - _PeekMessageA.argtypes = [POINTER(MSG), HWND, UINT, UINT, UINT] - _PeekMessageA.restype = BOOL - - _TranslateMessage = _user32.TranslateMessage - _TranslateMessage.argtypes = [POINTER(MSG)] - _TranslateMessage.restype = BOOL - - _DispatchMessageA = _user32.DispatchMessageA - _DispatchMessageA.argtypes = [POINTER(MSG)] - _DispatchMessageA.restype = LRESULT - msg = MSG() PM_REMOVE = 0x0001 - while _PeekMessageA(byref(msg), 0, 0, 0, PM_REMOVE): - _TranslateMessage(byref(msg)) - _DispatchMessageA(byref(msg)) + while PeekMessage(byref(msg), 0, 0, 0, PM_REMOVE): + TranslateMessage(byref(msg)) + DispatchMessage(byref(msg)) class Test(ut.TestCase): diff --git a/comtypes/test/test_git.py b/comtypes/test/test_git.py index 90978579..05f48244 100644 --- a/comtypes/test/test_git.py +++ b/comtypes/test/test_git.py @@ -7,7 +7,7 @@ from _ctypes import COMError from collections.abc import Iterator from ctypes import HRESULT, POINTER, OleDLL, WinDLL, byref -from ctypes.wintypes import BOOL, DWORD, HANDLE, HWND, MSG, UINT +from ctypes.wintypes import BOOL, DWORD, HANDLE, MSG from pathlib import Path from queue import Queue @@ -18,16 +18,11 @@ RegisterInterfaceInGlobal, RevokeInterfaceFromGlobal, ) -from comtypes.messageloop import DispatchMessage, TranslateMessage +from comtypes.messageloop import DispatchMessage, PeekMessage, TranslateMessage from comtypes.persist import STGM_READ, IPersistFile _user32 = WinDLL("user32") -# https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-peekmessagea -PeekMessage = _user32.PeekMessageA -PeekMessage.argtypes = [POINTER(MSG), HWND, UINT, UINT, UINT] -PeekMessage.restype = BOOL - # https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-msgwaitformultipleobjects MsgWaitForMultipleObjects = _user32.MsgWaitForMultipleObjects MsgWaitForMultipleObjects.restype = DWORD From 1ac90f249022af668edc8134208d50fe7190b5b0 Mon Sep 17 00:00:00 2001 From: junkmd Date: Sat, 7 Mar 2026 13:01:14 +0900 Subject: [PATCH 7/7] refactor: Centralize `PeekMessage` constants in `messageloop.py`. - Add `PM_NOREMOVE`, `PM_REMOVE`, and `PM_NOYIELD` constants to `messageloop.py`. - Update `test_eventinterface.py` and `test_git.py` to import `PM_REMOVE` from `messageloop`, removing redundant local definitions. --- comtypes/messageloop.py | 5 +++++ comtypes/test/test_eventinterface.py | 8 ++++++-- comtypes/test/test_git.py | 9 ++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/comtypes/messageloop.py b/comtypes/messageloop.py index 970e2ba5..fc545452 100644 --- a/comtypes/messageloop.py +++ b/comtypes/messageloop.py @@ -11,6 +11,11 @@ _FilterCallable = Callable[["_CArgObject"], Iterable[Any]] # type: ignore +# PeekMessage options +PM_NOREMOVE = 0x0000 +PM_REMOVE = 0x0001 +PM_NOYIELD = 0x0002 + _user32 = WinDLL("user32") GetMessage = _user32.GetMessageA diff --git a/comtypes/test/test_eventinterface.py b/comtypes/test/test_eventinterface.py index c7d8c6b2..9bfca80d 100644 --- a/comtypes/test/test_eventinterface.py +++ b/comtypes/test/test_eventinterface.py @@ -3,7 +3,12 @@ from ctypes.wintypes import MSG from comtypes.client import CreateObject, GetEvents -from comtypes.messageloop import DispatchMessage, PeekMessage, TranslateMessage +from comtypes.messageloop import ( + PM_REMOVE, + DispatchMessage, + PeekMessage, + TranslateMessage, +) # FIXME: External test dependencies like this seem bad. Find a different # built-in win32 API to use. @@ -45,7 +50,6 @@ def DocumentComplete(self, this, *args): def PumpWaitingMessages(): msg = MSG() - PM_REMOVE = 0x0001 while PeekMessage(byref(msg), 0, 0, 0, PM_REMOVE): TranslateMessage(byref(msg)) DispatchMessage(byref(msg)) diff --git a/comtypes/test/test_git.py b/comtypes/test/test_git.py index 05f48244..990627ec 100644 --- a/comtypes/test/test_git.py +++ b/comtypes/test/test_git.py @@ -18,7 +18,12 @@ RegisterInterfaceInGlobal, RevokeInterfaceFromGlobal, ) -from comtypes.messageloop import DispatchMessage, PeekMessage, TranslateMessage +from comtypes.messageloop import ( + PM_REMOVE, + DispatchMessage, + PeekMessage, + TranslateMessage, +) from comtypes.persist import STGM_READ, IPersistFile _user32 = WinDLL("user32") @@ -44,8 +49,6 @@ QS_ALLINPUT = 0x04FF # All message types including SendMessage -PM_REMOVE = 0x0001 # Remove message from queue after Peek - APTTYPE_MAINSTA = 3 RPC_E_WRONG_THREAD = -2147417842 # 0x8001010E