AutoHotKey while loop breaks - autohotkey

$*e::
While GetKeyState("e","P")
{
Send, {Blind}e
Sleep, 10 ; every 10 miliseconds
}
Return
Every few uses the while loop breaks and keeps spamming forever until i press the bind again.

Although I am still unable to replicate this issue, based on what #Charlie Armstrong mentioned, the script may work properly if SendEvent is used instead of a SendInput. The following modified script would still keep the SendMode as Input, but would override only the Send statement inside the while loop.
$*e::
While GetKeyState("e","P")
{
SendEvent, {Blind}e
Sleep, 10 ; every 10 miliseconds
}
Return
More information about Send and SendMode can be found here and here.

Related

AutoHotKey, Repeat key press

All I want is a simple keypress of lowercase "v" 4 times with a 1 second delay between. I have tried so many iterations of this simple-sounding action to no avail and the most infuriating thing is that I can get it to work with a capital "V" – but that also emulates a shift+v key press. I just don't understand.
v::
Loop, 4
{
sleep 10
SendInput {V} ; capital V works perfectly fine but includes Shift+v, I don't want a shift
sleep 1000
}
return
Whereas ...
v::
Loop, 4
{
sleep 10
SendInput {v} ; Lowercase v, Does absolutely nothing...
sleep 1000
}
return
What am I missing?
Try
$v::
Loop, 4
{
sleep 10
SendInput v
sleep 1000
}
return
The $ prefix works by forcing the keyboard hook to be used and prevents the Send command from triggering the hotkey itself.
Alternative #UseHook can be specified somewhere above, so the keyboard hook is implemented for every hotkey after it
Another solution:
#IfWinActive ahk_class your_app_ahk_class
$v::
SetKeyDelay, 1000
Send {v 4}
Return
I don't know what's the purpose of this, but since the shortcut does not include any control keys, it might be better to limit this to a specific app. The first line in my snippet tries to achieve this.

How to get ExitApp to take effect immediately in AHK?

If I run the following code, if I hit the ^+q it does not stop entering the numbers 1-100. Only after it completes does the script exit. Is there a way to get the script to stop even if it is in the middle of sending keystrokes?
^j::
ArrayCount := 100
Loop % ArrayCount
{
Send, %A_index%
}
return
^+q::ExitApp ; Exit script with Escape key
There are 2 issues with your code.
Sendreleases modifier keys when it simulates input, using it in a loop this way is going to interfere with autohotkey's hotkey detection. You can still activate ^+q if you press the 3 buttons simultaneously but it's much easier to use a hotkey without modifiers for example the Escape key. This is also what your comment says you're doing
^+q::ExitApp ; Exit script with Escape key
so as a bonus it will fix the discrepancy between your comment and your code ;).
The second problem is that the loop in which you execute the Send command is going to finish very quickly if you use SendInput and by the time ExitApp is executed all the numbers were already sent(even if you don't yet see the effect). In case of SendEvent there is some other problem which prevents other threads from being executed when you do it in a loop(don't know what causes it, might be a bug).
To solve it you need to add Sleep. At my system doing Sleep 1 works well. You can experiment with different numbers and send modes until you get the desired effect(you can also try 0 and -1.
Full code:
^j::
ArrayCount := 100
Loop % ArrayCount
{
Send %A_index%
Sleep 1 ; experiment with how long to sleep
}
return
Escape::ExitApp ; Exit script with Escape key

What in this script is causing my window to minimize?

The goal of this simple script is to detect an idle interval when a specific program is in focus and then send a simple keystroke when that idle interval has passed. I'm running this script on 4 PC's and I'm getting unexpected results. Some PC's minimize the window when the script runs. Other PC's run it as expected. The script is identical on each PC.
I'm invoking this script by right clicking on the script (that is, not running a compiled exe version of it). Running it as administrator seems to achieve better results on some clients, on one it makes no difference and minimizes the window.
As stated, on some PC's the script works as intended. There are no error messages, it just causes my window to minimize. Nothing in that code, to my newb eyes, should cause the window to minimize.
#Persistent
SetTimer, Timer_check,3000
Timer_check:
if WinActive("ahk_exe gta5.exe")
{
if (A_TimeIdlePhysical > 31301 && WinActive("ahk_exe gta5.exe")) {
Gosub, keepActive
ToolTip, We're currently idle TimeIdle is %A_TimeIdle% and TimeIdlePhysical is %A_TimeIdlePhysical%
sleep 1000
ToolTip
}
if (A_TimeIdle < 31301) {
ToolTip
}
}
return
keepActive: ; keep active sub.
if WinActive("ahk_exe gta5.exe")
{
Send, {` down} ; Press the ` key to keep us active. It holds the key for 0.2 seconds.
Sleep 200
Send, {` up}
}
return```
You're trying to send the accent/backtick, which is default escape character in AHK (`). To fix this, send a different character or escape the escape character, like so:
Send, {`` down}
Sleep 200
Send, {`` up}
Without it being escaped, it just sends the down- and up-keys. The WinKey+down combination minimizes a non-maximized window and that may somehow be related to why you're seeing the game window occasionally minimized.
https://www.autohotkey.com/docs/commands/_EscapeChar.htm
Edit: Added script for testing
#Persistent
SetTimer, Timer_check, 3000
Timer_check:
If WinActive("ahk_exe gta5.exe") {
If (A_TimeIdlePhysical > 31301 && WinActive("ahk_exe gta5.exe")) {
Send , z
ToolTip, We're currently idle TimeIdle is %A_TimeIdle% and TimeIdlePhysical is %A_TimeIdlePhysical%
sleep 1000
ToolTip
}
If (A_TimeIdle < 31301)
ToolTip
}
Return

Simple keypress script with loop in Autohotkey

Whenever you press w you get into a loop that press e around every 10 seconds. Another button has to be pressed to get out of it again at any moment (and making it possible to start over again). This is what I have so far:
w::
Loop
{
Send, e
Random, SleepAmount, 9000, 10000
Sleep, %SleepAmount%
x::Break
}
Return
I don't understand why it is not working yet. It presses e once and doesn't do anything anymore after that.
x::Break
is the short form for
x::
break
return
and therefore terminates the current subroutine. Never define a hotkey within any other execution bodies. Instead, define the x-hotkey outside the w hotkey and make it stop the loop.
Example using goTo (note that goSub is different for the latter will not terminate the subroutine):
w::
Loop {
send e
Random, SleepAmount, 9000, 10000
Sleep, %SleepAmount%
}
after_loop:
return
x::
goTo after_loop
return
; or, more compact:
; x::goto after_loop
Since gotos are pretty bad programming style, you might consider using a timer (instead of the loop). But to be honest, it's not worth it because your sleep amount is not fix.

AHK Prevent Multiple Hotkey Triggers

It's a quite simple code.
I just want my Mousewheeldown to Send P only once.
Even if I scroll it like 3 times, I only want it to send P only once every 100ms or sth.
Here is my really small bit of code so far:
SetKeyDelay , -1, 50
#NoTrayIcon
#NoEnv
#persistent
#MaxMem 2
WheelDown::
Send {p}
return
Sleeping a bit after sending the keystroke would solve this problem.
WheelDown:
Send, p
Sleep, 100
return
Also, you do not need to put the p between {}-s (curly braces), as it is not a special key.
The sleep command takes it's parameter as milliseconds, so if for example you would want to allow it only one 'p' in a second, you would write Sleep, 1000.