Я разрабатываю приложение на Python и хочу получить HWND каждого открытого окна. Мне нужно имя окон и HWND для фильтрации списка, чтобы управлять некоторыми специфическими окнами, перемещая и изменяя их размеры.

Я пытался сделать это сам, просматривая информацию, но я не получил правильный кусок кода. Я пытался с этим кодом, но я получить только заголовок каждого окна (это здорово), но мне тоже нужен HWND.

import ctypes
import win32gui
EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible

titles = []
def foreach_window(hwnd, lParam):
    if IsWindowVisible(hwnd):
        length = GetWindowTextLength(hwnd)
        buff = ctypes.create_unicode_buffer(length + 1)
        GetWindowText(hwnd, buff, length + 1)
        titles.append((hwnd, buff.value))
    return True
EnumWindows(EnumWindowsProc(foreach_window), 0)

for i in range(len(titles)):
    print(titles)[i]

win32gui.MoveWindow((titles)[5][0], 0, 0, 760, 500, True)

Здесь есть ошибка:

win32gui.MoveWindow((titles)[5][0], 0, 0, 760, 500, True)
 TypeError: The object is not a PyHANDLE object
7
user1618465 1 Фев 2013 в 22:56

4 ответа

Лучший ответ

Вы перепутали ctypes и win32gui.
Полученный вами hwnd получается через ctypes и является LP_c_long объектом. Вот почему win32gui.MoveWindow не принял это. Вы должны передать это

ctypes.windll.user32.MoveWindow(titles[5][0], 0, 0, 760, 500, True)

Если вы хотите использовать win32gui.MoveWindow, вы можете напрямую использовать функцию python в качестве обратного вызова.
Например,

import win32gui

def enumHandler(hwnd, lParam):
    if win32gui.IsWindowVisible(hwnd):
        if 'Stack Overflow' in win32gui.GetWindowText(hwnd):
            win32gui.MoveWindow(hwnd, 0, 0, 760, 500, True)

win32gui.EnumWindows(enumHandler, None)
24
nymk 1 Фев 2013 в 20:16

Чтобы получить дескрипторы всех доступных главных окон, вы передаете 0 в win32gui.EnumChildWindows, а затем убедитесь, что текст окна имеет длину больше 0 (поскольку вы хотите, чтобы только реальные окна не были скрыты / временные / всплывающие / специальные окна).

1
Script and Compile 1 Фев 2013 в 19:14

Ваша проблема (теперь, когда martineau исправила исходную проблему отсутствия хранения значений HWND) заключается в том, что вы пытаетесь смешать ctypes и win32gui.

Вы можете сделать это, если знаете, что делаете, но если нет, просто не делайте этого.

Если вы хотите получить дескрипторы окон, которые можно использовать с win32gui, используйте {{X1 }} вместо вызова необработанной функции из библиотеки user32.

2
abarnert 1 Фев 2013 в 20:07

Просто измените фрагмент кода для получения всех названий, поэтому он делает что-то вроде этого:

titles.append((hwnd, buff.value))

Список titles будет тогда списком кортежей, содержащим HWND и текст заголовка.

1
martineau 1 Фев 2013 в 19:22