How to use counters with variables, error: %%, Autohotkey - autohotkey

In a loop I want to use a counter to use different variables.
The problem is that both use the % symbol: %VAR%
Showing where I get the error %%, Simplified:
textGH1 = Peter
textGH2 = rocks.
i = 1
Loop, 2
{
SendInput {Enter}
Sleep 50
SendInput, %textGH%i%%
Sleep 50
SendInput {Enter}
i++
}
Error: Empty variable reference %%
What I tried:
I have looked up arrays for autohotkey, but I only found
pseudo-arrays using the %COUNTER% as a workaround, similiar to how I
did it. Second, I have assigned a variable in the loop to your current variable:
text := textGH%i%
However this doesn't call the variable, as expected (needed %textGH%i%% again)

I think I understand what you are trying? Swap variables when the counter changes. Easiest way to do this is with an Array.
Here's a solution for you play with:
Define Array. Array's Index values automatically, so Peter is at Index 1 Rocks is at Index 2.
MyArray := ["Peter", "Rocks"]
Loop amount of times as there are Values in your Array.
Loop, % MyArray.MaxIndex() {
SendInput {Enter}
Sleep 50
Send your Array at [Index] A_Index is a built in counter for Loops.
SendInput % MyArray[A_Index]
Sleep 50
SendInput {Enter}
}
Hope this helps.

This should work:
SendInput, %textGH%%i%

Related

How to press and hold 3 keys one after the other

New to Auto Hotkey. I’m looking to create a hotkey to press and hold Control, then press and hold Alt, then press “W”, then let go of all 3 and do the same after 30 seconds.
I tried this but unsure if it’s right. Thanks!
#SingleInstance, force
#MaxThreadsPerHotkey 2
F10::
Toggle := !Toggle
while Toggle
{
Send, {Ctrl}
Send, {Alt}
Send, {W}
Sleep, 30000 ;
}
Return
This should work:
#SingleInstance, force
F10::
Toggle := !Toggle
if (Toggle)
{
gosub, sub
SetTimer sub, 30000
}
else{
SetTimer sub, Off
}
Return
sub:
Send ^!w
return
Notes:
When a sleep command is used, the program is unable to detect hotkeys being pressed. Instead of using multiple threads, it would be better to implement a SetTimer/ Subroutine system.
In order to send Ctrl+Alt+W, just use Send ^!w. (^ means Control, ! means Alt, and and w means w; for more info, see modifiers.

Autohotkey - Attemping to send a specific position of an array

I am attempting to send a specific part of an array
My code is attempting to type a string a specified number of times.
If anyone knows a better way to do this I am open to ideas
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
i = 0 ; Used for a loop
InputBox, x, String, Please enter your string
InputBox, y, No. of times, Please enter the no. of times you want to run the string
k = `n ;used to concatenate strings
z = %x%%k% ;concatenating the input with new lines
F10::
while (i < y) { ;While the loop has run less than the required number of times
i++ ;increment the number of times the loop has run
l = 0 ;used to run a loop a certain number of times
a = StrSplit(%s%) ;Splits the string created earlier
send %a% ;For debug
g = 0 ;used as a value for cycling through arrays
while (l < StrLen(s)) {
h = a[g] ;creates a variable for a specified position in the string
g++
Random, rand, 10, 100 ;creates a variable to wait a random amount of time
r = %rand% ;assigns a random value to a variable for debug
FileAppend, Loop - %h% `n, C:\Users\charl\Desktop\Code\AutoHotkey\Debug.txt ;all file usage is for debug
FileAppend Rand - %r% `n `n, C:\Users\charl\Desktop\Code\AutoHotkey\Debug.txt
send %h% ;sends a character of the original string
Sleep %r% ;sleeps a random amount of time
}
}
I'm sorry the code is such a mess and so hard to udnerstand
The code that works for this specific function is:
InputBox, str, String, Please enter your string
InputBox, amt, No. of times, Please enter the no. of times you want to run the string
Return
F10::
Loop, %amt% {
For k,v in StrSplit(str) {
ToolTip, now %A_Index%
Random, rand, 10, 100 ;creates a variable to wait a random amount of time
;FileAppend %v%`n`n, %A_WorkingDir%\Debug.txt
Send, % v "`n"
Sleep, % rand ;sleeps a random amount of time
}
}

How do i parse a variable in a function to being able to define which variable to send?

This is my code
IniRead, custommessage1, whisperconfig.ini, messages, Message1
IniRead, custommessage2, whisperconfig.ini, messages, Message2
^NumPad1::whispermessage(1)
whispermessage(var){
finalwhisper := "custommessage" + var ;this equals custommessage1
Msgbox, %finalwhisper%
BlockInput On
SendInput ^{Enter}%finalwhisper%{Enter} ;<-- problem
BlockInput Off
return
}
So in the first line i am importing the value of custommessage1 (it could be "hi im henrik"). This is what i wish to end up getting as a output.
Inside the function i want the var (which is 1 in this case) to be merged with a variable called custommessage ending with a result of custommessage1
i want the endresult to do a SendInput %custommessage1%.
this way i can have one function for up to 9 triggers including var numbers.
Can anyone help? i am sure this is fairly simple however i am new to this coding thing so bear with me.
Your function only knows about its own variables, the ones you pass in as parameters, and global variables.
You're trying to access custommessage1, which is outside the function and isn't global. You either need to make all your variables global, or pass them in to the function.
I suggest the latter, using an array. Here's an example, make sure you're running the latest version of AHK for this to work properly.
IniRead, custommessage1, whisperconfig.ini, messages, Message1
IniRead, custommessage2, whisperconfig.ini, messages, Message2
; Store all messages in an array
messageArray := [custommessage1, custommessage2]
; Pass the array and message you want to print
^NumPad1::whispermessage(messageArray, 1)
whispermessage(array, index){
; Store the message at the given index in 'finalwhisper'
finalwhisper := array[index]
Msgbox, %finalwhisper% ; Test msgbox
; Print the message
BlockInput On
SendInput ^{Enter}%finalwhisper%{Enter}
BlockInput Off
}
Alternatively, and this is outside the scope of your question, you could load the keys from the .ini file dynamically, meaning you wouldn't have to create new variables each time you added a key/value pair.
Here's how you could do that:
; Read all the key/value pairs for this section
IniRead, keys, whisperconfig.ini, messages
Sort, keys ; Sort the keys so that they are in order
messageArray := [] ; Init array
; Loop over the key/value pairs and store all the values
Loop, Parse, keys, `n
{
; Trim of the key part, and only store the value
messageArray.insert(RegExReplace(A_LoopField, "^.+="))
}
; Pass the array and message you want to print
^NumPad1::whispermessage(messageArray, 1)
whispermessage(array, index){
; Store the message at the given index in 'finalwhisper'
finalwhisper := array[index]
Msgbox, %finalwhisper% ; Test msgbox
; Print the message
BlockInput On
SendInput ^{Enter}%finalwhisper%{Enter}
BlockInput Off
}

Use of application name with space(s) with WinExist

So I wanted to check if certain application exists or not.
If it does and there was no input within 4.5 min, switch to that app and perform some task.
Basically an AFK cheater.
This is what I have so far:
#SingleInstance force
#Persistent
settimer, idleCheck, 1000; check every second
return
idleCheck:
if WinExist(App Name with Spaces); if app is running
{
if(A_TimeIdle >= 270000); and there was no input in 4.5 min
{
WinActivate; switch to that app
sendInput z; and perform an action
}
}
return
Now obviously that doesn't work since I'd not be posting here otherwise.
The question is very simple yet I couldn't find an answer.
Thanks in Advance.
WinExist is a function and function parameters are expressions...
In expressions you need to use double quotes " around strings and you don't need % around variables
you also need to have a space before the semicolon to use comments
#SingleInstance force
#Persistent
settimer, idleCheck, 1000 ; check every second
return
idleCheck:
if WinExist("App Name with or without Spaces") ; if app is running
{
if(A_TimeIdle >= 270000) ; and there was no input in 4.5 min
{
WinActivate ; switch to that app
sendInput z ; and perform an action
}
}
return
Hope it helps

Using GetKeyState() and loops

I'm trying to write a script that has a loop in which the upper arrow key is pressed every two seconds. The loop must be activated when I press the spacebar and deactivated when I press it again. I'm now using this.
$Space::
if GetKeyState("Space", "P")
{
Loop
{
Sleep 2000
Send {Up}
if GetKeyState("Space", "P")
{
return
}
}
}
For some reason, the if condition inside the loop doesn't work, i.e. I can't get out of the loop. I hope anyone can help me out...
You wouldn't need the first if GetKeyState("Space", "P")
and you would need to be holding space when the loop got to the second one
for it to break; and you would need to replace the return with break.
However I agree with Gary, although I would write it like this:
; (on:=!on) reverses the value of variable 'on'
; the first press of space reverses on's value (nothing) to something (1)
; the second press reverses on's value from (1) to (0)
; when (on = 1) delay will be set to 2000, and Off when (on = 0)
space::SetTimer, Action, % (on:=!on) ? ("2000") : ("Off")
Action:
Send, {up}
Return
% starts an expression.
From http://l.autohotkey.net/docs/Variables.htm
?:
Ternary operator
This operator is a shorthand replacement for the if-else statement.
It evaluates the condition on its left side to determine
which of its two branches will become the final result.
For example, var := x>y ? 2 : 3 stores 2 in Var if x is greater than y; otherwise it stores 3.
How about using SetTimer?
; Create timer.
SetTimer, SendUp, 2000
; Set timer to 'Off' at start of script.
SetTimer, SendUp, Off
TimerEnabled := False
; When Space is pressed toggle the state of the timer.
$Space::
If TimerEnabled
{
SetTimer, SendUp, Off
TimerEnabled := False
}
Else
{
SetTimer, SendUp, On
TimerEnabled := True
}
; Label called by timer to send {Up} key.
SendUp:
Send, {Up}
return