My script breaks down at some point, I've eliminated all the syntax errors the debugger was able to spot - autohotkey

This is a script that is supposed to use the windows snipping tool to sequentially screencap pictures from an online gallery. If anyone can spot the problem that would be much appreciated.
#SingleInstance, Force
a := 112
name :=1
x:: Pause, Toggle
y:: ExitApp
Loop, a
{
MouseClickDrag, Left, 1300, 210, 645, 140
Sleep, 100
MouseClick, Left, 1277, 1038, 0, 5
sleep, 100
MouseClick, Left, 838, 64, 0, 5
sleep, 100
SendInput, %name%
name ++
sleep, 100
SendInput, {Enter}
Sleep, 100
MouseClickDrag, Left, 670, 13, 1393, 153
Sleep, 100
MouseClick, Left, 500, 490, 0, 5
Sleep, 300
MouseClick, Left, 500, 490, 0, 5
SendInput, {Right}
}

Two problems in it.
Firstly, your loop is unreachable code.
Code execution stops when your first hotkey label is encountered. This is called the Auto-execute Section.
Secondly, loop doesn't take an expression to the first parameter. It takes a legacy text parameter. So you'd either want to use the legacy way of referring to a variable, which would be %a%, but personally I'd push you towards using the modern expression syntax and forcing an expression to that parameter by starting the parameter off with a % followed up by a space. So Loop, % a.
To read more about legacy syntax vs expression syntax, see this page of the documentation.
Here's your fixed script:
#SingleInstance, Force
a := 112
name := 1
Sleep, 3000
Loop, % a
{
MouseClickDrag, Left, 1300, 210, 645, 140
Sleep, 100
MouseClick, Left, 1277, 1038, 0, 5
Sleep, 100
MouseClick, Left, 838, 64, 0, 5
Sleep, 100
SendInput, % name
name++
Sleep, 100
SendInput, {Enter}
Sleep, 100
MouseClickDrag, Left, 670, 13, 1393, 153
Sleep, 100
MouseClick, Left, 500, 490, 0, 5
Sleep, 300
MouseClick, Left, 500, 490, 0, 5
SendInput, {Right}
}
;this return here ends the auto-execute section
;but of course, in this specific case it's totally
;useless since the next line is a hotkey label
;which would also stop the auto-execute section
return
;even though the code execution gets stuck inside the loop,
;hotkeys can be specified down here
;they're created even before the auto-execute section starts
x::Pause, Toggle
y::ExitApp

Related

Need help on AHK script closing when pixel change

Hello I am fairly new to coding and I’m making a programme for a game I play on AHK, I’m trying to code a script so that when a pixel changes colour on my screen the script will completely stop whilst remaining part of the loop. The main code works but I've tried to add a system where the script will stop running if a pixel changes colour. Thanks for the help in advance.
Esc::ExitApp
+r::
sleep, 1000
Send, {e down}
Send, {e up}
sleep, 10750
loop {
PixelGetColor, color1, 949, 269
if(color1 = “0xA6A6A6”)
sleep, 500
SendInput {Esc}
IfWinActive ahk_exe FiveM_GTAProcess.exe
sleep, 5550
Send, {e down}
Send, {e up}
sleep, 500
MouseClick Left, 649, 390
sleep, 500
MouseClick Left, 964, 484
sleep, 500
MouseClick Left, 1311, 415
sleep, 500
loop, 4
{
MouseClick Left, 964, 484
sleep, 500
}
sleep, 500
MouseClick Left, 720, 415
sleep, 500
}
Add Break after your if:
if(color1 = “0xA6A6A6”)
Break
if(color1 = “0xA6A6A6”)
{
sleep, 500
SendInput {Esc}
}

How do I convert string to interger in AHK

I have this code below and I would like to get a string like "0,0" convert to integer and sum boths variable putting it on a new variable.
I was looking for solution in internet but without sucess.
code:
MouseMove, 238,282
MouseClickDrag, Left, 238,282, 238,282
Sleep, 200
Send, {CTRLDOWN}c{CTRLUP}
CLIPWAIT, 0.5
SaldoContabil = %ClipBoard% ; here is getting 0,0
Sleep, 400
MouseMove, 602,283
MouseClickDrag, Left, 602,283, 602,283
Sleep, 500
Send, {CTRLDOWN}c{CTRLUP}
CLIPWAIT, 0.5
ArredAcumulado = %ClipBoard% ; here is getting 0,0
Sleep, 400
baixa = %ArredAcumulado% - %SaldoContabil%
Add the following lines before the final calculation.
StrReplace just replaces the , with a . so from 0,0 you get 0.0, no further conversion is necessary.
SaldoContabil := StrReplace(SaldoContabil,",",".")
ArredAcumulado := StrReplace(ArredAcumulado ,",",".")

How to change the loop?

The script is searching for a certain text in the clipboard. When found, it shows a MsgBox.
I would like this script to stop when the text has been found. How to achieve that?
#Persistent
MouseMove, 821, 700
Sleep, 500
MouseClick, Left
Sleep, 500
Loop, 5
{
Send, ^c
Sleep, 500
Send, {PgDn}
}
OnClipboardChange:
If InStr( Clipboard, "Part3" )
SetTimer, PopupMsgBox, -1
Return
PopupMsgBox:
Msgbox, Part3 Found
Return
#Persistent
clip_search := "Part3"
MouseMove, 821, 700
Sleep, 500
MouseClick, Left
Sleep, 500
Loop, 5
{
Send, ^c
ClipWait
If InStr( Clipboard, clip_search )
{
MsgBox, % clip_search " Found."
Break
}
Sleep, 500
Send, {PgDn}
}

Autohotkey: Merging/combining two scripts in one script (#if WinActive, 2 actions)

I have 2 scripts I want to merge in one file, however when I put them together, only the first one gets executed:
Script 1:
#if WinActive("ahk_exe program.EXE")
#Persistent
Loop
{
WinWaitActive, Wizard
Send, !{F4}
}
Return
Script 2:
#if WinActive("ahk_exe program2.EXE")
#Persistent
Loop
{
WinWait, ahk_class bosa_sdm_Mso96
; IfWinNotActive, ahk_class bosa_sdm_Mso96, ,WinActivate, ahk_class bosa_sdm_Mso96
; WinWaitActive, ahk_class bosa_sdm_Mso96
; Sleep, 0
ControlMove, RichEdit20W6, 20, 850, 750, 25 ;Adress box
ControlMove, SysTreeView321, , , 800, 700
ControlMove, TreeViewCFParent1, , , 1000, 700
ControlMove, SysTreeView322, , , 800, 700
ControlMove, TreeViewParent1, , , 760, 940
WinMove, ahk_class bosa_sdm_Mso96, , 600, 50, 1000, 900 ; 900 width
}
Return
I tried removing or changing the location of "#Persistent", "Loop", "Return".. or adding #if at the end of each script.. still only the first one gets executed.. Even when trying to #Include the first script in the second, the first only gets executed. Maybe it needs "else" or something.. not sure..
The #If directive is only used for creating context-sensitive hotkeys and hotstrings.
If you use WinWait or WinWaitActive the script waits until the (first) window exists or becomes active and doesn't go any further to move the second window.
Without WinWait the CPU usage of the script is high.
The better solution in this case is SetTimer:
#Persistent
SetTimer, Close_Move_Windows, 500
return
Close_Move_Windows:
IfWinActive, Wizard
WinClose
IfWinExist, ahk_class bosa_sdm_Mso96
{
WinGetPos, X, Y, Width, Height, ahk_class bosa_sdm_Mso96
If (X != 600 || Y != 50 || Width != 900 || Height != 1000) ; "!" means "NOT" and "||" means "OR"
{
ControlMove, RichEdit20W6, 20, 850, 750, 25 ;Adress box
ControlMove, SysTreeView321, , , 800, 700
ControlMove, TreeViewCFParent1, , , 1000, 700
ControlMove, SysTreeView322, , , 800, 700
ControlMove, TreeViewParent1, , , 760, 940
WinMove, ahk_class bosa_sdm_Mso96,, 600, 50, 900, 1000 ; 900 width
}
}
Return

Unstoppable script Issue

I have a script wich uses several mousemoves and, when needed, I press F3 to stop the moves forcing a reload or ESC to stop the moves exiting the app. It works fine with no issues in the regular speed.
The problem is: when I decrease the mousespeed and increase the mousedelay, the script becomes unstoppable: I press the F2, F3 and ESC keys several times (trying to make it stops) but the script ignores it and continues running the mousemoves.
Here's a minimal example of my problem:
SendMode Input
$F1::
SetDefaultMouseSpeed, 50
SetMouseDelay, 30
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
SoundPlay, *48
return
$F2:: Pause
$F3:: Reload
$ESC:: ExitApp
Why does it happens and how can I fix it (how can I stop the script even with low speed+high delay)?
ps: F1 key starts the mousemoves sequence.
MouseMove with non-zero speed cannot be interrupted by another hotkey inside the same AHK script because Autohotkey is single-threaded internally (it just emulates thread-like behavior) and performs a blocking sleep for each mouse micromovement until it reaches the overall distance you specified.
Solutions:
Check whether a hotkey was pressed after each MouseMove, but it's non-instantaneous;
Implement your own MouseMove that checks GetKeyState after each 1px movement;
Use a master script with hotkeys that run/pause/stop the child:
Stopping: trivial, use Process Close
Running: the child should hide tray icon otherwise it'll stay after process close
Pausing: nontrivial but there are solutions (see also the underlying mechanics).