Skip to content

Commit 3d2b0ec

Browse files
bramddlech
authored andcommitted
Provide a local definition of user32.SetTimer, user32.KillTimer and ole32.CoGetApartmentType on Windows
By overriding the type definition of SetTimer, we prevent None being passed as the callback parameter. This causes problems when integrating Bleak in larger Windows applications that call SetTimer in this way. By defining the function type definition locally, we don't override the global definition so existing code that uses None as a callback keeps working. To prevent other problems, we also make the definitions of KillTimer and CoGetApartmentType local.
1 parent 5d6d145 commit 3d2b0ec

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

AUTHORS.rst

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Contributors
2323
* Robbe Gaeremynck <[email protected]>
2424
* David Johansen <[email protected]>
2525
* JP Hutchins <[email protected]>
26+
* Bram Duvigneau <[email protected]>
2627

2728
Sponsors
2829
--------

CHANGELOG.rst

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
1010
`Unreleased`_
1111
=============
1212

13+
Changed
14+
-------
15+
* In bleak.backends.winrt.util the SetTimer, KillTimer and CoGetApartmentType functions define their own prototype and don't change ctypes' global state anymore
16+
1317
`0.22.2`_ (2024-06-01)
1418
======================
1519

bleak/backends/winrt/util.py

+30-11
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,43 @@ def _check_hresult(result, func, args):
3636
)
3737

3838
# https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer
39-
_SetTimer = ctypes.windll.user32.SetTimer
40-
_SetTimer.restype = _UINT_PTR
41-
_SetTimer.argtypes = [wintypes.HWND, _UINT_PTR, wintypes.UINT, _TIMERPROC]
39+
_SET_TIMER_PROTOTYPE = ctypes.WINFUNCTYPE(
40+
_UINT_PTR, wintypes.HWND, _UINT_PTR, wintypes.UINT, _TIMERPROC
41+
)
42+
_SET_TIMER_PARAM_FLAGS = (
43+
(1, "hwnd", None),
44+
(1, "nidevent"),
45+
(1, "uelapse"),
46+
(1, "lptimerfunc", None),
47+
)
48+
_SetTimer = _SET_TIMER_PROTOTYPE(
49+
("SetTimer", ctypes.windll.user32), _SET_TIMER_PARAM_FLAGS
50+
)
4251
_SetTimer.errcheck = _check_result
4352

4453
# https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-killtimer
45-
_KillTimer = ctypes.windll.user32.KillTimer
46-
_KillTimer.restype = wintypes.BOOL
47-
_KillTimer.argtypes = [wintypes.HWND, wintypes.UINT]
48-
54+
_KILL_TIMER_PROTOTYPE = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, _UINT_PTR)
55+
_KILL_TIMER_PARAM_FLAGS = (
56+
(1, "hwnd", None),
57+
(1, "uidevent"),
58+
)
59+
_KillTimer = _KILL_TIMER_PROTOTYPE(
60+
("KillTimer", ctypes.windll.user32), _KILL_TIMER_PARAM_FLAGS
61+
)
4962

5063
# https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cogetapartmenttype
51-
_CoGetApartmentType = ctypes.windll.ole32.CoGetApartmentType
52-
_CoGetApartmentType.restype = ctypes.c_int
53-
_CoGetApartmentType.argtypes = [
64+
_CO_GET_APARTMENT_TYPE_PROTOTYPE = ctypes.WINFUNCTYPE(
65+
ctypes.c_int,
5466
ctypes.POINTER(ctypes.c_int),
5567
ctypes.POINTER(ctypes.c_int),
56-
]
68+
)
69+
_CO_GET_APARTMENT_TYPE_PARAM_FLAGS = (
70+
(1, "papttype", None),
71+
(1, "paptqualifier", None),
72+
)
73+
_CoGetApartmentType = _CO_GET_APARTMENT_TYPE_PROTOTYPE(
74+
("CoGetApartmentType", ctypes.windll.ole32), _CO_GET_APARTMENT_TYPE_PARAM_FLAGS
75+
)
5776
_CoGetApartmentType.errcheck = _check_hresult
5877

5978
_CO_E_NOTINITIALIZED = -2147221008

0 commit comments

Comments
 (0)