var1 := "this works"
#If WinActive("")
d::d
#If
var2 := "this doesn't"
x::
MsgBox, %var1%, %var2%
return
When the hotkey is triggered, it only displays var1, acting like var2 doesn't exist at all.
Why does this happen and what can I do to access var2 from the hotkey?
I can't move var2 up, since my actual code is split accross two files.
You cannot define a variable between or after hotkeys or hotstrings.
Hotkeys/Hotstrings terminate the automatic execution of code lines and the line
var2 := "this doesn't"
never becomes true because is never executed.
A variable has to be defined
in the auto-execute section (top of the script before the first return or hotkey),
or in a hotkey/hotstring,
or in a label (subroutine),
or in a function.
Related
In this problem setXTowerLocation() is called, a message box than appears after exiting the message box the function getXCords() is called in which it continuously scans checking the keyState of Lbutton once it detects that its pushed down the getxCords() function returns the x value of the cords of the mouse, which in turned gets set to a global variable in the setXTowerLocation() function before returning and displaying the x cord in a message box. Every time i run it the message box comes up blank, i have tested aspects of the code and they all seem to work individually so i believe it must be an error in syntax?
The ending message box is only for testing purposes. Thanks in advance :)
SendMode Input
Global xTowerLocation =
setXTowerLocation()
MsgBox, 0, MessageBox, %xTowerLocation%
getxCords()
{
xCord =
Loop,
{
GetKeyState, state, Lbutton
if(state = "D")
{
MouseGetPos, xx, yy
xCord := %xx%
return
}
}
return xCord
}
setXTowerLocation() {
MsgBox, 0, MessageBox, Begin?
IfMsgBox OK
xTowerLocation := getxCords()
return
}
Yes, syntax error in that xCord is referenced to a variable named after the contents (the mouse coord). Fix these two lines in getxCords() so xCord holds the value of the variable xx as follows:
xCord := xx
return xCord
And then no xCord on that later return (at end of the function).
EDIT: For even more fun, make the above xCord line as follows:
xCord := "x= " . xx . " , y= " . yy
I just discovered that if I try to use a global variable inside a function that is declared after a simple hotkey, a warning appears saying that this global variable doesn't has a value.
Illustration:
In this example, when I press Shift + l the warning appears.
Can anyone explain ?
Variables have to be declared in the auto-execute section or within a hotkey/hotstring/or another function.
#Warn
global a := "10/10" ; super-global variable
$+p:: Pause
$+1:: foo()
foo(){
MsgBox % "a = " . a
}
or
to access global variables within a function you need to add global within the function:
#Warn
a := "10/10" ; global variable
$+p:: Pause
$+1:: foo()
foo(){
global
MsgBox % "a = " . a
}
or:
#Warn
$+1::
global a := "10/10"
foo()
return
$+p:: Pause
foo(){
MsgBox % "a = " . a
}
For more details read Local and Global Variables
I'm having a problem with accessing the %1% ( Startup Param that has been passed to the Script by the console ) in Autohotkey.
When I use the following code (outside of a function):
Msgbox %1%
I get the output of the Param that has been passed to the Script. But as soon as I use the following Code:
HelloWorld() {
Msgbox %1%
}
HelloWorld()
The output is empty.
I also tried to assign %1% to a global variable, or to pass it to the Function as a parameter but it didn't work for me neither.
Thank you
I believe the command line parameter variables are considered global variables, so in order to use them in a non-expression context inside a function you have to declare them as global:
HelloWorld() {
global 1
Msgbox %1%
}
HelloWorld()
It gets even more confusing once you want to use them in expressions (such as using % in the text argument for MsgBox), since they will be treated as numbers so you have to indirectly access them through variables:
HelloWorld() {
;global 1
; Neither of these two expressions access the variable named "1"
;Msgbox % 1
;Msgbox % %1%
; You have to do this instead:
p := 1
MsgBox % %p% ; p is translated to 1 and then "1" is used as a variable name
}
HelloWorld()
Note that doing this doesn't require global 1.
If you're using the newest version of AHK, you instead probably want to use the newly introduced built-in variable A_Args, which is an array that holds the command line parameters. Being built-in, it doesn't have to be declared global, and it ultimately makes the code clearer:
HelloWorld() {
MsgBox % "Number of command line args received: " A_Args.Length() "`n"
. "First argument: " A_Args[1]
}
HelloWorld()
Just declare your cli variables as Global - outside the function - to make them globally available to any and all internal functions. For me, this is how I do it with my version of AHK (Version 1.1.25.01):
Global 1, 2, 3
HelloWorld() {
MsgBox Hello`t1:`t%1%`n`t2:`t%2%`n`t3:`t%3%
}
HelloWorld()
Note, these are different command lines:
"Scripts\myScript.ahk" one two three
"Scripts\myScript.ahk" "one two" three
"Scripts\myScript.ahk" "one" "two three"
"Scripts\myScript.ahk" "one two three"
The first is three separate parameters, the second and third, only two and the last is only one param (2 and 3 exist, but are empty).
Hth,
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
}
supposedlyGlobalVariable := "blah"
ARoutine()
{
localVariable := "asdf"
MsgBox, The global variable value is %supposedlyGlobalVariable%. The local variable value is %localVariable%.
}
^!X:: ;This assigns the hotkey CTRL + ALT + X to run the routine
ARoutine()
return
Run the code and the result is:
"The global variable value is . The local variable value is asdf."
The documentation states:
Variable scope and declarations: With the exception of local variables
in functions, all variables are global; that is, their contents may be
read or altered by any part of the script.
Why does my global variable not have scope within the function?
The documentation for global variables can be found here:
https://autohotkey.com/docs/Functions.htm#Global
Global variables
To refer to an existing global variable inside a function (or create a
new one), declare the variable as global prior to using it. For
example:
LogToFile(TextToLog)
{
global LogFileName
FileAppend, %TextToLog%`n, %LogFileName%
}
I believe the concept of global, with AHK, is a bit different than in other languages. With AHK you can create a variable and use it within multiple hotkeys, and subroutines, without declaring it as global.
Gv := 0
f1::SetTimer, Action, % (on:=!on) ? (1000) : ("Off")
Action:
Gv++
trayTip,, % Gv
Return
f2::Msgbox, % Gv
Explaination of code:
The F1 key toggles a timer to run the subroutine: Action every 1000ms.
% starts an expression.
on:=!on reverses the binary value of variable on every time F1 is pressed.
?: together is called the ternary operator.
When on=1 delay is set to 1000ms; when on=0 the timer is turned Off.
The ++ operator adds 1 to variable Gv.
This makes things easier:
https://www.autohotkey.com/docs/Functions.htm#SuperGlobal
Super-global variables [v1.1.05+]: If a global declaration appears
outside of any function, it takes effect for all functions by default
(excluding force-local functions). This avoids the need to redeclare
the variable in each function. However, if a function parameter or
local variable with the same name is declared, it takes precedence
over the global variable. Variables created by the class keyword are
also super-global.
Just declare your variable as global in the main script:
global supposedlyGlobalVariable := "blah"
P.Brian, It works when you do this.. I know it doesn't explain why, but this might be your workaround.
#Persistent
GlobalVariable = "blah"
RETURN
ARoutine:
{
localVariable := "asdf"
MsgBox, The global variable value is %GlobalVariable%. The local variable value is %localVariable%.
}
Return
^!X:: ;This assigns the hotkey CTRL + ALT + X to run the routine
gosub, ARoutine
return
You just need to declare the variable as global inside your function
supposedlyGlobalVariable := "blah"
ARoutine()
{
global supposedlyGlobalVariable
localVariable := "asdf"
MsgBox, The global variable value is %supposedlyGlobalVariable%. The local variable
value is %localVariable%.
}
^!X:: ;This assigns the hotkey CTRL + ALT + X to run the routine
ARoutine()
return