1

Тема: AHK: Нажатие определённых клавиш, при появлении cmd

Необходимо при появлении cmd нажать m->enter->enter.
Подскажите.
Не нашёл на форуме. Может плохо искал.

2 (изменено: creature.ws, 2012-09-27 14:33:44)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

DllCall("RegisterShellHookWindow", "UInt", A_ScriptHwnd) ; регистрируем скрытое окно скрипта в качестве получателя «уведомлений о событиях»
OnMessage(DllCall("RegisterWindowMessage", "str", "SHELLHOOK"), "ShellProc") ; регистрируем функцию в качестве обработчика получаемого сообщения SHELLHOOK http://msdn.microsoft.com/en-us/library/windows/desktop/ms644989%28v=vs.85%29.aspx
OnExit, Esc
return

Esc::
    DllCall("DeregisterShellHookWindow", "UInt", A_ScriptHwnd) ; http://msdn.microsoft.com/en-us/library/windows/desktop/ms644979%28v=vs.85%29.aspx
    ExitApp

ShellProc(wParam, lParam)
{
    static HSHELL_WINDOWCREATED := 1 ; http://msdn.microsoft.com/en-us/library/windows/desktop/ms644991%28v=vs.85%29.aspx
    global consoleWindowHWND

    if (wParam = HSHELL_WINDOWCREATED) {
        WinGetClass, winClass, ahk_id %lParam%
        if (winClass = "ConsoleWindowClass") {
            consoleWindowHWND := lParam
            SetTimer, ConsoleWindowCreated, -1
        }
    }
}

ConsoleWindowCreated:
    SetKeyDelay, 10, 10
    ControlSend,, {vk4D}{Enter}{Enter}, ahk_id %consoleWindowHWND%
    return

3 (изменено: creature.ws, 2012-11-07 18:53:58)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Ниже — общий пример, возможно он будет востребован.

; две нижележащие функции должны быть выполнены прежде чем ожидается требуемое поведение кода,
; например в секции авовыполнения.
OnWindowCreated("ahk_class ConsoleWindowClass", "ConsoleWindowCreated") ; первый параметр — window title в стандартном формате ahk, второй параметр — имя процедуры, которая должна выполнятся при создании окна с заданными первым параметром характеристиками
OnWindowActivated("ahk_class ConsoleWindowClass", "ConsoleWindowActivated") ; первый параметр — window title в стандартном формате ahk, второй параметр — имя процедуры, которая должна выполнятся при активации окна с заданными первым параметром характеристиками
return ; конец секции автовыполнения. не обязателен, но приемлем.

ConsoleWindowCreated(hWnd) ; эта процедура будет выполнятся при каждом создании окна консоли
{
    MsgBox %A_ThisFunc%:`n hWnd = %hWnd%
}

ConsoleWindowActivated(hWnd) ; эта процедура будет выполнятся при каждой активации окна консоли
{
    MsgBox %A_ThisFunc%:`n hWnd = %hWnd%
}

; ниже — служебные функции которые уместно держать в отдельном файле и в скрипт включать посредством #Include
OnWindowCreated(winTitle, procName = -1, maxThreads = 1)
{
    return ManageShellHookEventListeners("HSHELL_WINDOWCREATED", winTitle, procName, maxThreads)
}

OnWindowActivated(winTitle, procName = -1, maxThreads = 1)
{
    return ManageShellHookEventListeners("HSHELL_WINDOWACTIVATED", winTitle, procName, maxThreads)
}

ManageShellHookEventListeners(hookCode, ByRef winTitle, ByRef procName, ByRef maxThreads)
{
    static ShellHookEventList
    static HookCodeList := {HSHELL_WINDOWCREATED: 1, HSHELL_WINDOWACTIVATED: 4}

    if !hookCode := HookCodeList[hookCode]
        return false

    IsObject(ShellHookEventList) || ShellHookEventList := ShellProc(-1, 0) ; здесь копируем ссылку
    IsObject(ShellHookEventList[hookCode]) || ShellHookEventList[hookCode] := Object()

    if (procName = -1)
        return ShellHookEventList[hookCode][winTitle].Name

    else if (procName = "")
        return ShellHookEventList[hookCode].Remove(winTitle).Name

    else if IsFunc(procName) {
        shellhookWM := DllCall("RegisterWindowMessage", "Str", "SHELLHOOK", "UInt")

        if !OnMessage(shellhookWM) {
            DllCall("RegisterShellHookWindow", "Ptr", A_ScriptHwnd, "Int")
            OnMessage(shellhookWM, "ShellProc", maxThreads)
        }

        if !priorProcName := ShellHookEventList[hookCode].Remove(winTitle).Name
            priorProcName := procName

        ShellHookEventList[hookCode][winTitle] := Func(procName)
        return priorProcName
    }

    else return false
}

ShellProc(wParam, lParam)
{
    static ShellHookEventList := {} ; здесь инициализируем

    if ShellHookEventList.HasKey(wParam) {
        for winTitle, Proc in ShellHookEventList[wParam]
            if WinExist(winTitle . " ahk_id" . lParam)
                %Proc%(lParam)
    }
    else if (wParam = -1)
        return ShellHookEventList  ; возвращаем по запросу ссылку на статический объект, не захламляем глобальное пространство имён
    else Sleep 0
}

4

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Последний пример пригодится, спасибо.
Вопрос возник по использованным в примерах событиям — они случаем не по принципу таймера работают? Какова их природа? ))

5 (изменено: bugagashi, 2012-09-28 11:52:13)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Необходим именно то, что в первом посте.
Мне никуда вставлять не надо.
Чтобы я запустил *.ahk и через 2 сек, при появлении командной строки, произошло нажатие m потом enter, потом enter.
Как ?
Но за помощь всё равно спасибо

6

Re: AHK: Нажатие определённых клавиш, при появлении cmd

DD, природу используемых событий можно попробовать постичь ознакомившись с информацией по ссылкам в коде сообщения #2.
Смотря что считать «природой таймера», очередь сообщений используется

bugagashi, попробуйте сформулировать желаемое однозначно и полно. Раз вы считаете приведенные примеры не применимыми, то «догадаться», что же вы таки желаете получить от кода в итоге, я не возьмусь.

7 (изменено: bugagashi, 2012-09-28 15:15:51)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

В какой то момент времени появляется cmd.
В нём необходимо нажать сначала m потом enter потом enter.
Я хочу скомпилировать *.ahk и поставить в автозагрузку.
т.к. такая задача появляется часто.
И ещё дополнение.
win7.

8

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Полагаю требуется автоматизировать ввод пользовательских данных в интерпретатор, который выдает какой-нибудь запрос типа "если хотите то-то - введите m" а после ввода и энтера, как это часто бывает, требует подтверждения типа "Вы точно-точно-точно уверены, что находитесь в здравом уме, ввели m и хотите того-то и того-то?".
Упоминание о 2-секундной задержке наводит на мысль, что скрипт, будучи запущенным, должен дождаться появления окна командной строки и выполнить действия, описанные выше.
Скрипт из второго поста все это и делает, но в русской раскладке посылает мягкий знак. Может это не устроило автора? Ну и в случае таки запроса подтверждения "энтер, потом энтер" может требовать более длительной паузы паузы.

BIG BROTHER IS WATCHING YOU.

9

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Берём пример из второго сообщения, запускаем или компилируем и ставим в автозагрузку. Запускаем cmd, в окно cmd отправляются нажатия m enter enter. Где несоответствие?

10

Re: AHK: Нажатие определённых клавиш, при появлении cmd

О, Вы тут. Вы лучше объясните, чем Вас не устроил пример из поста #2?

BIG BROTHER IS WATCHING YOU.

11

Re: AHK: Нажатие определённых клавиш, при появлении cmd

errore at line 60.
Line text: for winTattle? procName in и т.д
Вот это появляется.

12 (изменено: bugagashi, 2012-09-28 15:36:27)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Korobkof пишет:

Полагаю требуется автоматизировать ввод пользовательских данных в интерпретатор, который выдает какой-нибудь запрос типа "если хотите то-то - введите m" а после ввода и энтера, как это часто бывает, требует подтверждения типа "Вы точно-точно-точно уверены, что находитесь в здравом уме, ввели m и хотите того-то и того-то?".
Упоминание о 2-секундной задержке наводит на мысль, что скрипт, будучи запущенным, должен дождаться появления окна командной строки и выполнить действия, описанные выше.

верно.
Только ничего не спрашивает.
А просит ввести m enter enter.
спасибо.
За разъяснение.
Но скрипт всё равно не запускается.
Первая версия ничего не делает.
Вторая ошибку выдаёт.

13 (изменено: creature.ws, 2012-09-28 15:48:17)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Вы используете устаревшую версию Autohotkey. Актуальная — AHK_L

14

Re: AHK: Нажатие определённых клавиш, при появлении cmd

ConsoleWindowCreated:
hWnd = 724010
появляется такое окно
Больше ничего.

15 (изменено: creature.ws, 2012-09-28 16:29:02)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Вы бы таки определились какой пример собираетесь использовать. При использования второго примера без изменений «больше ничего» появляться и не должно.

(Диалог аргументирующий отсутствие пользы от комментариев в коде)

16

Re: AHK: Нажатие определённых клавиш, при появлении cmd

creature.ws пишет:

(Диалог аргументирующий отсутствие пользы от комментариев в коде)

Странный вывод, имхо. creature.ws, если кто-то не смог воспользоваться чем-либо, ещё не значит, что пользы нет вовсе.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17 (изменено: creature.ws, 2012-09-28 17:42:26)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Обобщающий вывод, те, кто понимают пользу от прочтения комментариев и не пренебрегают этой возможностью, «как правило» могут разобраться в компактном коде не прибегая к комментариям автора. Вот и выходит, что комментарии полезны лишь если код занимает более некого усреднённого количества строк, способных уместиться в «оперативной памяти» читающего.

Конкретно в этом случае — комментарии расчитанные на «начинающего пользователя» оказались бесполезны.

18

Re: AHK: Нажатие определённых клавиш, при появлении cmd

В данном случае — возможно, но знаю по себе, что если тема малознакома, грамотно комментированный код воспринимается гораздо легче.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19

Re: AHK: Нажатие определённых клавиш, при появлении cmd

И, кстати, подобные конструкции с несколькими уровнями вложенности

OnMessage(DllCall("RegisterWindowMessage", "str", "SHELLHOOK"), "ShellProc")

конечно, могут вызвать благоговейный ужас (если речь идёт о начинающем пользователе), но вряд ли способствуют пониманию материала.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

20

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Вложенность позволяет избежать использования объективно не востребованных переменных. Вникание в «ужасную» конструкцию способствует развитию начинающего пользователя, «готовит» его к тяжкому труду познания нового.

Если использование вложенной конструкции не вызывает необходимость пользоваться горизонтальной прокруткой — считаю это уместным

21

Re: AHK: Нажатие определённых клавиш, при появлении cmd

На всякий случай.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

22

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Извиняйте, но с ссылками не разобрался.
Если не в тягость, всё-таки: оно являет собой непрерывный этакий бешеный цикл или нечто более субтильное?

23

Re: AHK: Нажатие определённых клавиш, при появлении cmd

В теле примера циклов нет

24

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Ну да — намек был на подобие цикла.
Я, конечно, поднадоел , но будьте добры: иначе — сверка соответствия условиям осуществляется в каждый момент времени или только в момент поступления, условно говоря, какого-то сигнала от системы?

25 (изменено: creature.ws, 2013-02-05 07:34:28)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Только по сигналу от системы. Иначе бы зачем огород городить с OnMessage, если и проверка условия по таймеру работала бы так же?

26

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Задача выполнена.
Спасибо большое за помощь.

27

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Необходимо при появлении cmd нажать m->enter->enter.

А можно воспользоваться командой WinWait ?

28

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Скрипт, кстати, долго не работает.
Просто исчезает из программ.
Перезапускать приходиться.
Можно от этого избавиться?

29

Re: AHK: Нажатие определённых клавиш, при появлении cmd

ypppu пишет:

Необходимо при появлении cmd нажать m->enter->enter.

А можно воспользоваться командой WinWait ?

В том то и дело, что мне нужно чтобы он постоянно работал.

30 (изменено: creature.ws, 2012-10-07 04:39:10)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Скрипт, кстати, долго не работает.
Просто исчезает из программ.
Перезапускать приходиться.
Можно от этого избавиться?

Можно. Нужно лишь разобраться какой скрипт и почему исчезает, а после — устранить в конкретном скрипте конкретную недоработку.
Если вы о примере из третьего сообщения речь ведёте, то, при использовании в оригинальном виде, проблемы мной не замечены.

31

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Разобрался.
Спасибо, что помогли.

32

Re: AHK: Нажатие определённых клавиш, при появлении cmd

bugagashi пишет:
ypppu пишет:

Необходимо при появлении cmd нажать m->enter->enter.

А можно воспользоваться командой WinWait ?

В том то и дело, что мне нужно чтобы он постоянно работал.

Так я и не понял, что мешает использовать команду, идеально подходящую под описание поставленной задачи.

33

Re: AHK: Нажатие определённых клавиш, при появлении cmd

WinWait ( "title" [, "text" [, timeout]] )
Команда же ждёт, когда окно станет активно.
И выключает его после тайм-аута.
Мне это не нужно.

34

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Я тоже не понимаю к чему все эти сложности, когда можно использовать команду
IfWinExist

35

Re: AHK: Нажатие определённых клавиш, при появлении cmd

WinWait
Дожидается существования указанного окна.

WinWait [, WinTitle, WinText, Seconds, ExcludeTitle, ExcludeText]

Эта команда ждёт, пока появится окно. Она заменяет периодические проверки IfWinExist. А команда, которая ждёт, когда окно станет активно, называется WinWaitActive.

36

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Какие же ценные скрипты в постах 2 и 3.
Почему их еще нет в коллекции?

37

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Потому, что они понадобились лишь двум пользователям. Невостребованная функциональность у которой есть альтернативная реализация через WinWait.

38 (изменено: Malcev, 2012-11-06 03:22:46)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

А что в него нужно вписать, чтобы он находил не по WinGetClass, а WinGetTitle.
Так как WinGetClass возвращает #32770, а такое же имя классов у множества других окон.
Пробовал менять  WinGetClass на WinGetTitle - не распознает.

ЗЫ. И все-равно, я считаю, что такие нестандартные решения нужны для коллекции.
Если в ней покопаться, то там найдутся куда более бесполезные скрипты.

39

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Это частный случай. «Признаки окна» стандартные для команд используемых в ahk.  Если «не распознаёт» то значит окно с точки зрения системы «не создаётся» и «не активируется».

40

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Может я неправильно делаю.
Вот часть кода, который я исправил

ShellProc(wParam, lParam)
{
    static HSHELL_WINDOWCREATED := 1 ; http://msdn.microsoft.com/en-us/library/windows/desktop/ms644991%28v=vs.85%29.aspx
    global consoleWindowHWND
 
    if (wParam = HSHELL_WINDOWCREATED) {
        WinGetTitle, winTitle, ahk_id %lParam%
        if (winTitle = "Save Project") {
            consoleWindowHWND := lParam
            SetTimer, ConsoleWindowCreated, -1
        }
    }
}

Хотя командой

WinGetTitle, Title, A
MsgBox, The active window is "%Title%".

возвращает "Save Project"

41 (изменено: creature.ws, 2012-11-06 06:05:44)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Если «не распознаёт» то значит окно с точки зрения системы «не создаётся» и «не активируется».

Используйте winwait, как и планировали.

42 (изменено: DD, 2015-02-22 04:19:03)

Re: AHK: Нажатие определённых клавиш, при появлении cmd

Не возьму в толк, почему код не реагирует на окно диалога, хотя если подставить класс другого окна — сработает:

OnWindowCreated("ahk_class #32770", "Dialog32770_Created")
return

Dialog32770_Created(hWnd) ; эта процедура будет выполнятся при каждом создании окна
{
  Soundplay *48  ;Exclamation
  return
}

; ниже — служебные функции которые уместно держать в отдельном файле и в скрипт включать посредством #Include
OnWindowCreated(winTitle, procName = "", maxThreads = 1)
{
    global ShellHookActionList
 
    IsObject(ShellHookActionList) || ShellHookActionList := Object()
    IsObject(ShellHookActionList[1]) || ShellHookActionList[1] := Object()
 
    if procName
        ShellHookActionList[1][winTitle] := procName
    else
        return ShellHookActionList[1][winTitle]
 
    if !OnMessage(DllCall("RegisterWindowMessage", "str", "SHELLHOOK")) {
        DllCall("RegisterShellHookWindow", "UInt", A_ScriptHwnd)
        OnMessage(DllCall("RegisterWindowMessage", "str", "SHELLHOOK"), "ShellProc", maxThreads)
    }
}

ShellProc(wParam, lParam)
{
    global ShellHookActionList
 
    if ShellHookActionList.HasKey(wParam) {
        for winTitle, procName in ShellHookActionList[wParam] {
            WinGet, hWndList, List, %winTitle%
            loop %hWndList%
                continue
            until hWndList%A_Index% = lParam && found := true
 
            if (found)
                %procName%(lParam), found := false
        }
    }
    return
}

И вопрос между прочим: может ли сказаться на производительности множество десятков условий на событие (приведённого типа) в скрипте?