Доступ к MFC приложению средствами Python

Всем привет.

Пытаюсь разобраться с темой автоматизации тестирования Windows GUI приложения написанного на основе MFC (Microsoft Foundation Classes). До этого работал с приложениями основанными на WinAPI и каких либо проблем с программным доступом, например, к меню приложения не было. Для примера как я работаю с WinAPI приложением:

  • зная handle главного окна, функцией GetMenuBarInfo() получаю структуру MENUBARINFO;
  • получив handle MenuBar-a, функцией GetMenuItemCount() получаю количество пунктов меню, ищу пункт с необходимым названием, получаю его RECT и “кликаю” в центр этого прямоугольника и так далее.

С MFC приложением оказалось все не так просто, там WinAPI-шные функции уже не видят меню (из-за того что там используются совершенно другие классы).

Собственно прошу подсказать, кто уже сталкивался с MFC приложениями, как можно программно получить информацию о таких контроллах, какие библиотеки могут в этом помочь (пишу на Python) и в каком направлении вообще капать. Два для поисков в сети не дали никаких результатов.

Пользовался зарекомендовавшим себя средством автоматизации в Windows

Вот библиотека для интеграции в Python

AutoIT-ом я и так пользуюсь, но он так же работает только с WinAPI приложениями, меню MFC приложения она тоже не видит.

Прошу прощения, действительно не видит.
А это не пробовали?
http://pywinauto.github.io/

Ну и если не поможет - вот это

К сожалению pywinauto тоже не видит меню, дело в том, что в тестируемом приложении меню задано классом CMFCMenuBar и WinSpy++ видит его как Afx:ToolBar и от этого все стандартные средства работы с меню отпадаю. Sikuli с ее кликанием по картинкам это последнее, что хотелось бы использовать)
Все равно спасибо за подсказки, буду дальше думать что сделать, если найду решение отпишусь)

1 лайк

Добрый день. Забыл сразу отписаться о результатах анализа:)
Для работы с меню в MFC приложениях, которое определено как класс Afx:ToolBar, можно использовать сообщение TB_GETBUTTON, получить структуру пункта меню/кнопки панели инструментов и далее зная RECT этого элемента “кликнуть” в него. Есть один нюанс, TB_GETBUTTON возвращает пустую структуру для меню реализованного в программе с помощью CMFCMenuBar, в этом случае можно использовать сообщение TB_GETITEMRECT, в котором передается номер пункта меню, если меню не меняется динамически во время работы программы, то можно создать маску меню, и зная номер каждого пункта с помощью TB_GETITEMRECT получать его RECT.

1 лайк

Для такого тулбара можно сделать одну хитрость, чтобы получить тексты кнопок. Они есть через MS UI Automation, но откреплены от родительского тулбара и вообще от иерархии элементов приложения (так что от главного окна даже их не найти). Но, получив RECT’ы, можно использовать ElementFromPoint, взяв таким образом AutomationElement, у которого есть текст! Но это фактически аццкая смесь двух технологий. Хотим в pywinauto такое сделать, но это не самый высокий приоритет.

1 лайк

Спасибо за подсказку, сейчас тоже этим вопросом не занимаюсь, т.к. есть более приоритетные задачи. Как дойдут руки до этого функционала снова, попробую Ваш вариант разобрать поподробней)