1 (изменено: Clannad5, 2018-12-29 11:47:36)

Тема: AHK: Остановка цикла при нажатие клавиши

Здравствуйте!

Интересует вопрос:

Как остановить цикл, используя только один файл Скрипт Ahk, если он уже начался и идёт 2 минуты, а мне нужно остановить его в любой момент, при нажатие одной клавишей?


Возможна ли такая реализация?

Приведу пример кода, в котором нужно остановить цикл:

F1::
Loop
{
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
Msgbox, Hello World!
Sleep, 10000
}
Return

Есть ли функция, которую можно было бы вставить после Sleep, 10000, которая бы проверяла - нажимал я клавишу остановки или нет?


Я знаю что скрипт AHK работает только в одном потоке, поэтому даже не представляю, как можно сделать второй поток, который бы проверял наличие на нажатие клавиши, не применяя сюда второй файл Ahk.

Неужели никак?


P.S Не нужно код изменять на

F1::
Loop, 10
{
Msgbox, Hello World!
Sleep, 10000
}
Return

ибо тот пример я привёл так, как нужно.

2

Re: AHK: Остановка цикла при нажатие клавиши

KeyWait, If, Break — с помощью этих команд можно сделать замену Sleep.
С другой стороны можно перезапустить скрипт командой Restart.

3

Re: AHK: Остановка цикла при нажатие клавиши

stealzy

Мне нужно чтобы макрос работал бесконечно, до тех пор пока не нажму 1 раз кнопку, независимо от того, в какой строке цикла я это нажал.
keywait же не запомнит мою клавишу, если я её нажму перед командой Sleep или после неё, пока Sleep выполняется, верно?

Возможно я просто тугой и не понимаю без примера.

4

Re: AHK: Остановка цикла при нажатие клавиши

В обсуждениях форума встречаются подобные темы, если их поискать.
Как правило, если имеется основной рабочий цикл включающий множество процедур, но ответственный, чтобы все они проходили только в заданных условиях, а сами процедуры не были ответственны за их проверку, создаётся таймер, в теле которого происходит проверка на соответствие окружения этим условиям. А так же переменная-тумблер, описывающая состояние(ВКЛ/ВЫКЛ). Тело таймера, просто изменяет содержимое переменной, если условия не соответствуют ожиданиям.

Таймеры выполняются по КД.

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


state := false

F1::
	if (state := !state) {
		SoundBeep, 1500, 100
		ToolTip, ВЫКЛ
		SetTimer, Cycle, -1
		SetTimer, HideTooltip, -2000
	} else {
		ToolTip, ВЫКЛ
		SetTimer, HideTooltip, -2000
	}
Return

Cycle:
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	GoSub, HelloWorld
	Sleep, 10000
	SetTimer, Cycle, -1
Return

HelloWorld:
	if (!state) {
		SoundBeep, 1200, 100
		Exit
	}
	Msgbox, Hello World!
return
HideTooltip:
	ToolTip
return

Обратите внимание, что процедура Cycle не завершается сразу по нажатии F1. После выполнения подпрограммы HelloWorld, выполнение попадает в ожидание(Sleep) и пока оно не истечёт, не будет выполнена проверка состояния выполнения(state).

5

Re: AHK: Остановка цикла при нажатие клавиши

KeyWait может ждать пока вы не нажмете кнопку заданное кол-во секунд. Таким способом команда заменяет Sleep.
Если кнопка не была нажата за 10 секунд, то ErrorLevel будет содержать 1.
Следующей командой проверяете ErrorLevel и если кнопка была нажата делаете Break из цикла.

6 (изменено: serzh82saratov, 2018-12-29 17:49:14)

Re: AHK: Остановка цикла при нажатие клавиши

Была недавно тема, если одной и той же кнопкой то так ещё можно:


#if Loop
1::Loop := 0
#if !Loop
1::
	Loop := 1
	Loop
	{
		MsgBox,,First, % A_Index,0.1
		Sleep(200) 
		MsgBox,,Second, % A_TickCount,0.1
		Sleep(400) 
	}
	Return
#if

Sleep(Delay) {
	Global Loop
	Start := A_TickCount
 	While A_TickCount - Start < Delay && Loop
		Sleep 1
	If !Loop
		Exit
}

Если как таковой Sleep не нужен, то можно после каждой команды выполнять Sleep(-1) для проверки.

По вопросам возмездной помощи пишите письма E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.01 (Unicode 32-bit). AhkSpy, Hotkey

7

Re: AHK: Остановка цикла при нажатие клавиши

KusochekDobra

Ваш пример будет мне полезным.

Спасибо.