Страницы

Поиск по вопросам

четверг, 11 июля 2019 г.

Python. Поиск текста внутри окна программы

Возникла необходимость, используя 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 без оберток, например на Си, никогда не было.

Комментариев нет:

Отправить комментарий