Задать вопрос
@richardvanstark

Winapi, чужое приложение — проблемы с меню и окна отрисовываются только при наведении мыши?

Добрый день,

Моя операционная система Windows 8.1, есть приложение, которое написано на Java\SWT, доступа к исходным кодам нет.

Мне необходимо сделать некоторую автоматизацию, я делаю это через вызовы winapi.

Запускается программа отдельно, не через CreateProcess из программы, которая делает автоматизацию (не знаю, влияет ли это на что-нибудь).

Программа должна быть в фоновом режиме, то есть фокус стоит на другом окне, никак не связанном с ней.

Вопрос 1:

Главное меню, там где File, Help я ищу через вызов GetMenu - находит прекрасно, каждый раз.

Потом я вызываю GetSubMenu и GetMenuItemID соотвественно, чтобы найти пункт меню.

Проблема как раз в этом. GetMenuItemID выдает FFFFFFF - то есть она не находит пункт меню до тех пор, пока не кликнешь на пункт меню например File в самой программе, чтобы открылся список подменю.

Как только нажмешь, список подменю откроектся - находит нормально, пока программа некоторое время не постоит в простое - тогда снова подменю пропадает и выдает FFFFFFF.

Я перепробовал много различных команд посылать программе, но без успеха.

Каким образом можно реинициализировать меню, чтобы каждый раз не кликать для его инициализации?

Вопрос 2:

Приложение находится в фоновом режиме, фокус стоит на другом окне.

При нажатии на пункты меню через SendMessage, должен открыватся диалог с классом "#32770 (Dialog box)"

Проблема в том, что иногда происходит так, что диалоговые окна не открываются, пока... не наведешь мышью на область окна.

Я тестирую из консоли, консоль поверх окна программы, мышка находится на консоли. И ровно в момент того, как мышь наводится на заднее окно (именно просто наводится, без клика и активации), все диалоговые окна начинают рисоваться...

Если сделать SetForegroundWindow - то вроде бы все рисуется нормально, но тогда окно становится активным, а нужно чтобы оно было в фоновом режиме.

Вопрос 3:

Как определить, что диалоговое окно "#32770 (Dialog box)" открылось? Я долго искать в интернете, но почти все методы - это просто каждые N миллисекунд искать окно, а потом делать Sleep.

Вопрос 4:

Почему на разных компьютерах, все c Windows 8.1, программа работает по-разному?

На некоторых компьютерах SetForegroundWindow делает окно активным, то есть окно выскакивает на передний план.

На других SetForegroundWindow не делается активным, иконка программы в taskbar начинает мигать, но окно не выскакивает на передний план.

Иногда находит пункт подменю через GetMenuItemID, а иногда категорически отказывается, даже если активировать подменю через клик.

Спасибо.
  • Вопрос задан
  • 3886 просмотров
Подписаться 3 Оценить Комментировать
Решения вопроса 1
@Sumor
Ответ на 4 вопрос:
Когда деревья были маленькими, а Windows только появилась, то была функция SetActiveWindow, которая делала выбранное окно активным — выбрасывало на первый план. Но программисты любили делать свои окна постоянно активными и вызывали эту функцию слишком часто, от этого иногда система уходила в карусель активных окон. Для предотвращения этого в API Windows появилась функция SetForegroundWindow, которая работает почти также, но в случае частых вызовов окна перестают переключаться, а только начинают мигать в панели задач. Это не особенность компьютеров или программ — это внутренняя кухня. Если система решит, что вы слишком часто переключаетесь - она начнёт просто мигать кнопками.
Ответ на 3 вопрос:
Ожидание появление окна — в цикле, по таймеру. Ничего в этом страшного нет. При желании это можно организовать в отдельном потоке.
Помимо этого есть сложные методы внедрения кода в программу, связанные с хуками приложения или перехватом вызовов функций, но не думаю что ваша задача требует такого сложного вмешательства.
Ответ на 2 вопрос:
Видимо у программы так реализован цикл событий, что ваш SendMessage не обработается, пока не придут настоящие события - MOUSE_MOVE, например. Или для диалога нужно текущее активное окно. Или ещё много других подобных причин. Может перед SendMessage должно прийти другое событие.
В большинстве случаев для имитации действий нужно чтобы окно было активным. Если окно не активное, то имитация в равной степени может работать или не работать.
Ответ на 1 вопрос:
Скорее всего меню динамические и создаются по щелчкам мыши и открытию меню. Поэтому вам ничего не остаётся как последовательно имитировать нажатие на меню File, пробег по пунктам меню, и выбор нужного пункта меню — чтобы отработали внутренние механизмы создания подменю.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы