Возникла необходимость, используя Python, искать текст внутри окна программы. Причём зачастую внутри Label Box'ов.
Вот окошко из Micro-Cap, и мне, к примеру, надо найти слово Spectrum. Как такое реализовать?
Ответ
Если задача только под Windows, то вам нужны функции WinAPI FindWindow, FindWindowEx, GetWindowText, EnumChildWindows, инструмент типа Spy++ (чтобы получить информацию о классах искомых окон), а также библиотека, позволяющая вызывать эти функции (pywin32, например).
Примерный алгоритм:
Получить идентификатор (handle) окошка About по заголовку и классу окна (с помощью FindWindow). Класс окна можно узнать с помощью Spy++. Функция FindWindowEx позволяет найти окно по заголовку, классу окна, идентификатору родительского окна, идентификатору предыдущего дочернего окна родительского окна.
Получить идентификаторы дочерних окон (элементов управления) окошка About (с помощью функции EnumChildWindows)
С помощью функции GetWindowText получить текст дочерних окон и найти окно, содержащее искомый текст.
Бонус: можно найти кнопку и послать ей с помощью функции SendMessage сообщение о том, что по ней кликнули (BM_CLICK).
Также есть специальная библиотека pywinauto для упрощения подобных задач.
Обновление
Небольшой пример. Не стал разбираться, как передать callback-функцию в EnumChildWindows, сделал свою аналогичную функцию на основе FindWindowEx:
import win32gui
def enumerate_children(parent):
prev = None
while True:
cur = win32gui.FindWindowEx(parent, prev, None, None)
if not cur:
return
yield cur
prev = cur
Тестируем (открыто окно "о программе" блокнота):
>>> import win32gui
>>> wnd = win32gui.FindWindow(None, 'Блокнот: сведения')
>>> wnd
3867102
>>> [win32gui.GetWindowText(item) for item in enumerate_children(wnd)]
['', '', 'Майкрософт Windows', 'Версия 10.0 (сборка 10240)', '© Корпорация Майкрософт (Microsoft Corporation), 2015 г. Все права защищены.', 'Операционная система Windows 10 Домашняя для одного языка и пользовательский интерфейс в ней защищены правами на товарные знаки и иные объекты интеллектуальной собственности в США и других странах.', '', '', 'Microsoft', 'Microsoft', 'ОК']
Скриншот окна:
Часть текста по каким-то причинам не извлеклась, но в вашем случае, думаю, проблем не будет.
Еще одно: в msdn написано, что GetWindowText не работает с элементами управления окна чужого процесса, и текст чужих элементов управления можно получить только с помощью посылки сообщения WM_GETTEXT, однако, как видим, через win32gui.GetWindowText можно получить текст чужих элементов управления. Возможно, просто внутри библиотеки pywin32 GetWindowText реализован через посылку сообщения. Но насколько я помню, особых проблем с получением текста любого окна через GetWindowText без оберток, например на Си, никогда не было.
Комментариев нет:
Отправить комментарий