1 (изменено: elektrovenik, 2015-02-22 14:06:11)

Тема: Поиск множества окон одного процесса и отправка в них нажатий клавиш

Всем привет. Вот привела в замешательство реализация такой задачи:
Хочу сделать скрипт, который будет по имени процесса находить все созданные им окна и отправлять в них нажатие клавиши. Для простоты рассмотрим на примере блокнота


Search:
Loop {
Process, Exist, Calc.exe ; нашли процесс
PID := %name+1% ; - начинается первая запарка. Тут бы надо прописать математическую функцию сложения A+n= An. То есть цикл поиска пидов данного процесса, при нахождении каждого нового пида, должно присваивать ему имя переменной N+1. Для первого найденного окна это будет N, для второго N1, для третьего N2 и т.д
Gosub, SendKey
}

SendKey:
СontrolSend,, клавиша,  ahk_id %name+1%; Вот тут вторая заковырка. Нужна функция, которая будет подставлять в переменную %name+1% все найденные при поиске переменные с PID'ами процессов

Я конечно понимаю, что можно пойти простым путем и сделать так:


key x::
gosub, Search
return

Search:
Process, Exist, Calc.exe
PID := %name%
Process, Exist, Calc.exe
PID := %name1%
Process, Exist, Calc.exe
PID := %name2%
Process, Exist, Calc.exe
PID := %name3%
Process, Exist, Calc.exe
PID := %name4%
Gosub, SendKey
return

SendKey:
СontrolSend,, клавиша,  ahk_id %name%
СontrolSend,, клавиша,  ahk_id %name1%
СontrolSend,, клавиша,  ahk_id %name2%
СontrolSend,, клавиша,  ahk_id %name3%
СontrolSend,, клавиша,  ahk_id %name4%
return

Но это сгодится только если я знаю, сколько будет запущенно процессов и соответственно окон, а хочется добиться универсальности.
Как я написал выше, примерное понимание как это должно быть у меня есть, но технической оснащенности и знаний синтаксиса языка мне не хватает. Помогите пожалуйста примером, как это должно быть грамотно реализовано.

2

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

Process, Exist, Calc.exe ; нашли процесс
PID := %name+1% ; - начинается первая запарка. Тут бы надо прописать математическую функцию сложения A+n= An. То есть цикл поиска пидов данного процесса, при нахождении каждого нового пида, должно присваивать ему имя переменной N+1. Для первого найденного окна это будет N, для второго N1, для третьего N2 и т.д

Что за пиды данного процесса? У процесса только один пид. Если запущены два Калькулятора, то это два процесса, а не один. Присвоение имени переменной пиду — это вообще непонятно. Это просто технически неосуществимо. Пид назначается операционной системой и ничего вы ему не присвоите.

Я конечно понимаю, что можно пойти простым путем и сделать так:

А какой смысл так делать? Почему вы думаете, что повторный вызов Process, Exist не вернёт вам тот же самый пид, что и предыдущий вызов? Команда ведь не в курсе, что вы её уже вызывали, стало быть просто найдёт тот же самый процесс Calc.exe и вернёт вам тот же самый его пид.

если я знаю, сколько будет запущенно процессов и соответственно окон

У процесса может быть и несколько окон, в том числе скрытые.

Так что вам требуется? Все окна одного процесса? Все окна всех процессов с данным именем? В том числе скрытые окна?

3

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

WinGet MyPseudoArray, List, ahk_exe Calc.exe
while ID := MyPseudoArray%A_Index%
    MsgBox %ID%
Забыл пароль и потерял e-mail.

4 (изменено: elektrovenik, 2015-02-23 00:49:02)

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

Спасибо YMP за здравую критику и замечания. Теперь я почувствовал уровень своей технической безграмотности.
Задумка описана в первом посте:

Как пример отлично подходит ситуация, если запустить несколько приложений "Калькулятор"
Я хочу реализовать скрипт, который будет по нажатию клавиши находить все окна, созданные процессом Сalc.exe, а затем отправлять в каждое найденное окно нажатие клавиши.
В скрипте не нужно реализовывать постоянный циклический поиск окон (предполагается, что скрипт будет запущен уже после открытия всех окон, т.е. их потребуется найти один раз). Так же могу сказать, что окна не будут скрытыми.

Подскажите пожалуйста реализацию задумки.

P.S. Немного подумав, я понял, что условие поиска окон по PID родительского процесса не обязательно, просто мне оно казалось наиболее правильным. Можно предложить иную реализацию (WinWait / IfWinExist или как-то еще).

+ YMP

5

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

Подскажите пожалуйста реализацию задумки.

А что-такое в #3 ? Замени MsgBox на ControlSend...

Забыл пароль и потерял e-mail.

6

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

WinGet, OutputVar, List, ahk_exe calc.exe

В справке всё расписано.

7

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

ypppu пишет:
WinGet, OutputVar, List, ahk_exe calc.exe

В справке всё расписано.

Огромнейшее спасибо! С Вашей подсказкой получилось реализовать в таком виде:


Space::
WinGet, win, List, ahk_exe calc.exe
ControlSend,, 1, ahk_id%win1%
ControlSend,, 1, ahk_id%win2%
ControlSend,, 1, ahk_id%win3%
return

Но сразу же возникли вопросы:
Поиск через WinGet. Вы в нем очень здорово применили WinTitle ahk_exe calc.exe, но в справке этого нет.

+ открыть спойлер

Заголовок или часть заголовка окна (метод поиска можно задавать командой SetTitleMatchMode). Если этот и следующие 3 параметра опущены, будет использовано последнее найденное окно. Чтобы задать окно через его класс, используйте конструкцию ahk_class ТочноеИмяКласса (можно посмотреть программой Window Spy). Чтобы использовать идентификатор процесса (PID), задайте параметр как ahk_pid %ПеременнаяСодержащаяPID%. Чтобы использовать идентификатор окна, задайте параметр как ahk_id %ПеременнаяСодержащаяID%.

Из справки видны варианты определения ahk_class и ahk_pid. Откуда вы узнали, про возможность прописывать ahk_exe ?

Второй вопрос: мой вариант кода годится если только мне известно конечное количество окон. А как реализовать скрипт, для неизвестного мне количества окон?

8

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

ahk_exe был введён уже после того, как был сделан русский перевод этой страницы справки, поэтому он есть только в английской.

Количество найденных окон будет у вас в переменной win.


Space::
WinGet, win, List, ahk_exe calc.exe
Loop, %win%
{
    ControlSend,, 1, % "ahk_id" win%A_Index%
}
return

9

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

YMP пишет:

    ControlSend,, 1, % "ahk_id" win%A_Index%

Пожалуйста YMP, объясните образование этой строки. Я, к сожалению, настолько тугой, что не могу этого понять.
% "ahk_id" win%A_Index% - эта часть кода относится к параметру поиска WinTitle, но что в ней что я не понимаю(

10

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

Да, ahk_exe нужно смотреть в англоязычной справке.
Если читали внимательно, количество окон - не такое уж неизвестное.
В каких случаях обрамляется знаком %, а в каких знак % ставится впереди и с пробелом - читайте на русском языке Переменные и выражения (оригинал статьи в AutoHotkey.chm: "Variables and Expressions").

11 (изменено: YMP, 2015-02-23 12:54:46)

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

elektrovenik пишет:

% "ahk_id" win%A_Index% - эта часть кода относится к параметру поиска WinTitle, но что в ней что я не понимаю(

Здесь строка "ahk_id" соединяется с содержимым переменной по имени "win" + индекс цикла, чтобы сформировать параметр команды. Процент с пробелом говорит АНК о том, что дальнейший код нужно интерпретировать как выражение, а не как обычный параметр. Можно было и проще:


Space::
WinGet, win, List, ahk_exe calc.exe
Loop, %win%
{
    win_id := win%A_Index%
    ControlSend,, 1, ahk_id %win_id%
}
return

12

Re: Поиск множества окон одного процесса и отправка в них нажатий клавиш

Большое спасибо ypppu и YMP за советы, помощь и объяснения.