Тема: AHK: Нажатие определённых клавиш, при появлении cmd
Необходимо при появлении cmd нажать m->enter->enter.
Подскажите.
Не нашёл на форуме. Может плохо искал.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Необходимо при появлении cmd нажать m->enter->enter.
Подскажите.
Не нашёл на форуме. Может плохо искал.
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
Ниже — общий пример, возможно он будет востребован.
; две нижележащие функции должны быть выполнены прежде чем ожидается требуемое поведение кода,
; например в секции авовыполнения.
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
}
Последний пример пригодится, спасибо.
Вопрос возник по использованным в примерах событиям — они случаем не по принципу таймера работают? Какова их природа? ))
Необходим именно то, что в первом посте.
Мне никуда вставлять не надо.
Чтобы я запустил *.ahk и через 2 сек, при появлении командной строки, произошло нажатие m потом enter, потом enter.
Как ?
Но за помощь всё равно спасибо
DD, природу используемых событий можно попробовать постичь ознакомившись с информацией по ссылкам в коде сообщения #2.
Смотря что считать «природой таймера», очередь сообщений используется
bugagashi, попробуйте сформулировать желаемое однозначно и полно. Раз вы считаете приведенные примеры не применимыми, то «догадаться», что же вы таки желаете получить от кода в итоге, я не возьмусь.
В какой то момент времени появляется cmd.
В нём необходимо нажать сначала m потом enter потом enter.
Я хочу скомпилировать *.ahk и поставить в автозагрузку.
т.к. такая задача появляется часто.
И ещё дополнение.
win7.
Полагаю требуется автоматизировать ввод пользовательских данных в интерпретатор, который выдает какой-нибудь запрос типа "если хотите то-то - введите m" а после ввода и энтера, как это часто бывает, требует подтверждения типа "Вы точно-точно-точно уверены, что находитесь в здравом уме, ввели m и хотите того-то и того-то?".
Упоминание о 2-секундной задержке наводит на мысль, что скрипт, будучи запущенным, должен дождаться появления окна командной строки и выполнить действия, описанные выше.
Скрипт из второго поста все это и делает, но в русской раскладке посылает мягкий знак. Может это не устроило автора? Ну и в случае таки запроса подтверждения "энтер, потом энтер" может требовать более длительной паузы паузы.
Берём пример из второго сообщения, запускаем или компилируем и ставим в автозагрузку. Запускаем cmd, в окно cmd отправляются нажатия m enter enter. Где несоответствие?
О, Вы тут. Вы лучше объясните, чем Вас не устроил пример из поста #2?
errore at line 60.
Line text: for winTattle? procName in и т.д
Вот это появляется.
Полагаю требуется автоматизировать ввод пользовательских данных в интерпретатор, который выдает какой-нибудь запрос типа "если хотите то-то - введите m" а после ввода и энтера, как это часто бывает, требует подтверждения типа "Вы точно-точно-точно уверены, что находитесь в здравом уме, ввели m и хотите того-то и того-то?".
Упоминание о 2-секундной задержке наводит на мысль, что скрипт, будучи запущенным, должен дождаться появления окна командной строки и выполнить действия, описанные выше.
верно.
Только ничего не спрашивает.
А просит ввести m enter enter.
спасибо.
За разъяснение.
Но скрипт всё равно не запускается.
Первая версия ничего не делает.
Вторая ошибку выдаёт.
Вы используете устаревшую версию Autohotkey. Актуальная — AHK_L
ConsoleWindowCreated:
hWnd = 724010
появляется такое окно
Больше ничего.
Вы бы таки определились какой пример собираетесь использовать. При использования второго примера без изменений «больше ничего» появляться и не должно.
(Диалог аргументирующий отсутствие пользы от комментариев в коде)
(Диалог аргументирующий отсутствие пользы от комментариев в коде)
Странный вывод, имхо. creature.ws, если кто-то не смог воспользоваться чем-либо, ещё не значит, что пользы нет вовсе.
Обобщающий вывод, те, кто понимают пользу от прочтения комментариев и не пренебрегают этой возможностью, «как правило» могут разобраться в компактном коде не прибегая к комментариям автора. Вот и выходит, что комментарии полезны лишь если код занимает более некого усреднённого количества строк, способных уместиться в «оперативной памяти» читающего.
Конкретно в этом случае — комментарии расчитанные на «начинающего пользователя» оказались бесполезны.
В данном случае — возможно, но знаю по себе, что если тема малознакома, грамотно комментированный код воспринимается гораздо легче.
И, кстати, подобные конструкции с несколькими уровнями вложенности
OnMessage(DllCall("RegisterWindowMessage", "str", "SHELLHOOK"), "ShellProc")
конечно, могут вызвать благоговейный ужас (если речь идёт о начинающем пользователе), но вряд ли способствуют пониманию материала.
Вложенность позволяет избежать использования объективно не востребованных переменных. Вникание в «ужасную» конструкцию способствует развитию начинающего пользователя, «готовит» его к тяжкому труду познания нового.
Если использование вложенной конструкции не вызывает необходимость пользоваться горизонтальной прокруткой — считаю это уместным
Извиняйте, но с ссылками не разобрался.
Если не в тягость, всё-таки: оно являет собой непрерывный этакий бешеный цикл или нечто более субтильное?
В теле примера циклов нет
Ну да — намек был на подобие цикла.
Я, конечно, поднадоел , но будьте добры: иначе — сверка соответствия условиям осуществляется в каждый момент времени или только в момент поступления, условно говоря, какого-то сигнала от системы?
Только по сигналу от системы. Иначе бы зачем огород городить с OnMessage, если и проверка условия по таймеру работала бы так же?
Задача выполнена.
Спасибо большое за помощь.
Необходимо при появлении cmd нажать m->enter->enter.
А можно воспользоваться командой WinWait ?
Скрипт, кстати, долго не работает.
Просто исчезает из программ.
Перезапускать приходиться.
Можно от этого избавиться?
Необходимо при появлении cmd нажать m->enter->enter.
А можно воспользоваться командой WinWait ?
В том то и дело, что мне нужно чтобы он постоянно работал.
Скрипт, кстати, долго не работает.
Просто исчезает из программ.
Перезапускать приходиться.
Можно от этого избавиться?
Можно. Нужно лишь разобраться какой скрипт и почему исчезает, а после — устранить в конкретном скрипте конкретную недоработку.
Если вы о примере из третьего сообщения речь ведёте, то, при использовании в оригинальном виде, проблемы мной не замечены.
Разобрался.
Спасибо, что помогли.
ypppu пишет:Необходимо при появлении cmd нажать m->enter->enter.
А можно воспользоваться командой WinWait ?
В том то и дело, что мне нужно чтобы он постоянно работал.
Так я и не понял, что мешает использовать команду, идеально подходящую под описание поставленной задачи.
WinWait ( "title" [, "text" [, timeout]] )
Команда же ждёт, когда окно станет активно.
И выключает его после тайм-аута.
Мне это не нужно.
Я тоже не понимаю к чему все эти сложности, когда можно использовать команду
IfWinExist
WinWait
Дожидается существования указанного окна.WinWait [, WinTitle, WinText, Seconds, ExcludeTitle, ExcludeText]
Эта команда ждёт, пока появится окно. Она заменяет периодические проверки IfWinExist. А команда, которая ждёт, когда окно станет активно, называется WinWaitActive.
Какие же ценные скрипты в постах 2 и 3.
Почему их еще нет в коллекции?
Потому, что они понадобились лишь двум пользователям. Невостребованная функциональность у которой есть альтернативная реализация через WinWait.
А что в него нужно вписать, чтобы он находил не по WinGetClass, а WinGetTitle.
Так как WinGetClass возвращает #32770, а такое же имя классов у множества других окон.
Пробовал менять WinGetClass на WinGetTitle - не распознает.
ЗЫ. И все-равно, я считаю, что такие нестандартные решения нужны для коллекции.
Если в ней покопаться, то там найдутся куда более бесполезные скрипты.
Это частный случай. «Признаки окна» стандартные для команд используемых в ahk. Если «не распознаёт» то значит окно с точки зрения системы «не создаётся» и «не активируется».
Может я неправильно делаю.
Вот часть кода, который я исправил
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"
Если «не распознаёт» то значит окно с точки зрения системы «не создаётся» и «не активируется».
Используйте winwait, как и планировали.
Не возьму в толк, почему код не реагирует на окно диалога, хотя если подставить класс другого окна — сработает:
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
}
И вопрос между прочим: может ли сказаться на производительности множество десятков условий на событие (приведённого типа) в скрипте?
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться