Перечисление Windows через Ctypes в Python

Я пытаюсь получить список всех видимых окон, используя ctypes в Python3.3

Но с кодом, который у меня есть, ни одно окно не возвращается. EnumWindows функция завершается ошибкой, и возвращаемый код ошибки равен 0.

import ctypes

user32 = ctypes.windll.user32

def worker(hwnd, lParam):
    length = user32.GetWindowTextLengthW(hwnd) + 1
    buffer = ctypes.create_unicode_buffer(length)
    user32.GetWindowTextW(hwnd, buffer, length)
    print("Buff: ", repr(buffer.value))

a = ctypes.WINFUNCTYPE(ctypes.c_bool,
                       ctypes.POINTER(ctypes.c_int),
                       ctypes.POINTER(ctypes.c_int))(worker)

if not user32.EnumWindows(a, True):
    print("Err: ", ctypes.windll.kernel32.GetLastError())

Вот текущий вывод:

Buff:  ''
Err:  0

И это то, что я ожидал:

Buff: 'Python 3.3.2 shell'
Buff: 'test.py - C:\Users\...'
[...]

Не могли бы вы указать мне правильное направление для достижения этой цели? Заранее спасибо.

1 ответ

Решение

Обратный звонок должен вернуться TRUE продолжить перечисление. Ваш обратный вызов неявно возвращается None, что является ложным. Следующая исправленная версия должна делать то, что вы хотите:

import ctypes
from ctypes import wintypes

WNDENUMPROC = ctypes.WINFUNCTYPE(wintypes.BOOL,
                                 wintypes.HWND,
                                 wintypes.LPARAM)
user32 = ctypes.windll.user32
user32.EnumWindows.argtypes = [
    WNDENUMPROC,
    wintypes.LPARAM]
user32.GetWindowTextLengthW.argtypes = [
    wintypes.HWND]
user32.GetWindowTextW.argtypes = [
    wintypes.HWND,
    wintypes.LPWSTR,
    ctypes.c_int]

def worker(hwnd, lParam):
    length = user32.GetWindowTextLengthW(hwnd) + 1
    buffer = ctypes.create_unicode_buffer(length)
    user32.GetWindowTextW(hwnd, buffer, length)
    print("Buff: ", repr(buffer.value))
    return True

cb_worker = WNDENUMPROC(worker)
if not user32.EnumWindows(cb_worker, 42):
    raise ctypes.WinError()

HWND тип ручки является псевдонимом для c_void_p, LPARAM является целым числом, это тот же размер хранилища, что и указатель. Это определяется следующим образом wintypes:

if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):
    WPARAM = ctypes.c_ulong
    LPARAM = ctypes.c_long
elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):
    WPARAM = ctypes.c_ulonglong
    LPARAM = ctypes.c_longlong
Другие вопросы по тегам