I have the following working Python code that uses the module win32gui
to call the EnumChildWindows
function:
import win32gui
def func(hwnd, param):
param.append(hwnd)
return True
def code():
arr = []
win32gui.EnumChildWindows(win32gui.GetDesktopWindow(), func, arr)
print(arr)
code()
win32gui.EnumChildWindows
allows to pass, by reference, any Python object in the last argument.
I'm trying to do the same using the module ctypes
. The closest I have gotten is passing a C array instead of the Python list, though it's not passing by reference because when I change the variable inside the function it doesn't change its value outside.
Code below:
from ctypes import byref, POINTER, windll, WINFUNCTYPE
from ctypes.wintypes import BOOL, HWND, LPARAM
def func(hwnd, param):
c_arr = HWND * (len(param) + 1)
param = c_arr(*param)
param[len(param) - 1] = hwnd
print(str(param[len(param) - 1]))
return True
def code():
py_arr = []
c_arr = HWND * len(py_arr)
arr = c_arr(*py_arr)
WNDENUMPROC = WINFUNCTYPE(BOOL, HWND, HWND * len(py_arr))
windll.user32.EnumChildWindows.argtypes = [HWND, WNDENUMPROC, POINTER(HWND * len(py_arr))]
windll.user32.EnumChildWindows.restype = BOOL
windll.user32.EnumChildWindows(windll.user32.GetDesktopWindow(), WNDENUMPROC(func), byref(arr))
print(arr)
code()
After a while of searching and trying different things, I found the code of win32gui
in C.
It uses PyObject which corresponds to ctypes.py_object
.
Working code below:
from ctypes import byref, py_object, windll, WINFUNCTYPE
from ctypes.wintypes import BOOL, HWND
def func(hwnd, param):
param.append(hwnd)
return True
def code():
arr = []
WNDENUMPROC = WINFUNCTYPE(BOOL, HWND, py_object)
windll.user32.EnumChildWindows.argtypes = [HWND, WNDENUMPROC, py_object]
windll.user32.EnumChildWindows.restype = BOOL
windll.user32.EnumChildWindows(windll.user32.GetDesktopWindow(), WNDENUMPROC(func), arr)
print(arr)
code()