How do I call global variables in hotstring functions.
This works:
::hlw::
hlwvar = Hello World
sendInput %hlwvar%
return
This doesn't:
hlwvar = Hello World
::hlw::
sendInput %hlwvar%
return
I got this answer from "Joel T. 33 / M / Seattle, WA" through Aardvark. I'm posting it here because it was quite useful.
--
Your second form should actually work; try pasting just those 4 lines into a new script and run it to see. Most likely the problem is that in your second example, "hlwvar = Hello World" is not actually being executed because it isn't at the top of the script. When AHK first runs a script, it starts from the top and executes until it encounters a "return" or a hotstring/hotkey definition. Therefore, you should always define your global vars and any other global setup at the top of your script, and once all the script "initialization" stuff is done there, end it with a "return". Then put all your hotstrings/hotkeys/functions below that point.
One thing I like to do is put all my global stuff into a function, e.g.
Init()
{
global
someglobalvar = myvalue
return
}
Then at the top of my script I have
Init()
return
This makes it really easy to identify at a glance where my init stuff lives, as well as move the init routine elsewhere if desired. Note that the "global" keyword must be the first command in a function definition if you want all of the variables assigned inside said function to be available globally.
As Chris mentioned the following two codes work exactly the same for me:
::hlw::
hlwvar = Hello World
sendInput %hlwvar%
return
and
hlwvar = Hello World
::hlw::
sendInput %hlwvar%
return
Related
I was writing a pretty simple script to hold down left click. I am most likely over-complicating this, but I want to be able to exit the script when I want and have left click go up on exit. I tried a loop but I could not quite figure out how I would go about pausing it, since I want it to immediately go back to mouse down on an unpause. Anyway, here is the current code I am working with:
=::
click, down
-::ExitApp
OnExit("ClickUp")
ClickUp(ExitReason)
{
if ExitReason in Exit
{
click, up
}
}
return
The main problem is your OnExit("ClickUp") line being unreachable code.
It'll never get executed, and therefore your script doesn't have function defined to run on exit.
It's unreachable code, because your script ends code execution when the first hotkey label (=::) is reached.
This is called the auto-execute section.
To fix this, you'd just set the OnExit("ClickUp") line to be in your auto-execute section. Maybe make it the very first line in your script.
And since I called that the main problem, there has to be some other problems as well. I'd call the other problems cursed code.
=::
click, down
You never end the hotkey label's code execution. By luck there's nothing to be executed below, but this would very easily cause unwanted behavior.
End the code execution with a Return or use a single line hotkey as you can in this case:
=::click, down
if ExitReason in Exit
You were probably looking to do this:
if (ExitReason = "Exit")
Though, I wouldn't recommend it. I don't think you want this check at all, all the exit reasons should be fine(?)
And then the Return on the last line serves no purpose.
Here's your finished script:
OnExit("ClickUp")
=::Click, Down
-::ExitApp
ClickUp()
{
Click, Up
}
/*
Or, if the exit reason checking
was somehow needed, use this version
ClickUp(ExitReason)
{
if (ExitReason = "Exit")
Click, Up
}
*/
I am trying to assign a string to a variable, and then have a hotkey send that variable's value.
I already have a functioning example, where I use f1 to send a text string with some of the automatic Autohotkey variables such as %A_MM% %A_DD% and %A_YYYY% for quick and easy datestamps:
f1::
Send, (WTC %A_MM%/%A_DD%/%A_YYYY% %A_Hour%:%A_Min%) :{space} ; press f1
Return
I tried writing this to test:
v_test := "testing string in v_test"
f2::
MsgBox, %v_test%
RETURN
But the message box come up blank. Why isn't the message box displaying "testing string in v_test"?
The variables were never initialized because the variable was not contained within the auto-execute section of the autohotkey script.
To fix this, I had to put the variable declaration at the top of the script, before any RETURNs, EXITs, hotkeys, or hotscripts. I also could have written the variable as GLOBAL, inside of a function, then called the function.
In my main Autohotkey script I have several hundred hotstrings like these:
::fe::for example
::f::and
::fi::for instance
::fo::fortunate
::foy::fortunately
::glo::global
::gloy::globally
::ha::have
::hv::however
Fairly often it would be convenient to trigger a hotstring manually (e.g. by pressing ALT-9) rather than pressing and end character. Is there a way to do this? I haven't found anything in my Googling, so maybe there isn't. But it would be useful.
I've read the hotstrings options e.g. :*: but this isn't the same - I want normal hotstring operation, but also the option to manually force them to trigger as needed.
Updated:
So what you are in fact looking for is using ALT+9 as an end character. I'm not sure but you can probably not use key-combinations for that (see hotstring doc). I cannot think of a really clever way of doing that right now. You might try something like
::fe::
Transform, CtrlC, Chr, 3 ; comes from ahk input documentation, I never really understood how this is supposed to work but I guess there is a code for alt 9 as well somehow
input, key, L1 I M ; wait for the next 1 key
if(key==CtrlC)
sendraw forExample
return
Old answer:
You have to outsource the hotstring body:
::fe::gosub forExample
forExample:
send for example
return
, then you can define a hotkey somewhere:
!9::gosub forExample
If you want to be cool, use functions instead of subroutines.
Note:
::fe::something
is just a short form for
::fe::
send something
return
::fe::for example
::f::and
::fi::for instance
::fo::fortunate
::foy::fortunately
::glo::global
::gloy::globally
::ha::have
::hv::however
!8:: trigger_hotstring("fi")
!9:: trigger_hotstring("ha")
trigger_hotstring(hotstring){
Loop, Read, %A_ScriptFullPath%
{
If InStr(A_LoopReadLine, "::"hotstring "::")
{
SendInput, % StrSplit(A_LoopReadLine,"::"hotstring "::").2
break
}
}
}
If you use AutoHotkey v1.1.06+ you can use #InputLevel
::fe::for example
::f::and
; and so on
#InputLevel, 1 ; sending space will trigger hotstrings above this line
!F9::Send {space}
Edit:
I now see you want to omit the end char which needs a bit of extra work
One way would be to duplicate the hotstrings with additional options:
::fe::for example
:*O:fe_::for example ; duplicate the hotstrings like so
::f::and
::fi::for instance
::fo::fortunate
; and so on
#InputLevel, 1
!9::Send _
Another way would be to remove the endchar
::fe::for example
::f::and
::fi::for instance
::fo::fortunate
; and so on
#InputLevel, 1
!9::
Send {space}
Sleep 100 ; give it time to expand the hotstring, experiment with timing
Send {bs} ; now remove trailing space
Return
I generally use TAB as a trigger for all my hotstrings. like
:*:#pm ::mail1#protonmail.com
:*:#G ::mail2#gmail.com
:*:Btw ::By the way,{Left}
Note that the space that you see here is a tab and not a space. you can do this instead of doing Alt+9 to trigger your macro hotstring.
you can even use more than one Tab so you can be sure that you only trigger it when you really intend to.
I'm trying to make something for our employees to use so that they dont have to alter the script itself to define hotkeys. This may only work for hotkeys which can be defined by a single character, but that's fine, as there are so many combinations that can be made with them, and they can be very easy to remember. The script would look only at 2 character AHK files (or 6 if you must include the extension) in the working directory. And the variables it would search for could be defined with RegEx so for the first hotkey, it would look like ^. and then second would look like .(?=.) Once a match is found, it would simply launch that matched file. Has something like this been done before? It seems so simple but I can't seem to find anything on it.
Edit: Elliot brought this to my attention: http://autohotkey.com/board/topic/60630-easy-editmanage-hotkeyshotstrings-plugin-ahk-l/
It's a neat script manager, and very useful, but it's not what I'm looking for.
I dont not want an additional interface. I want to be able to change the hotkeys by using the filename.
Based on the answer of Forvin. Added the execution of the corresponding ahk script.
#Persistent
SetTimer, FindNewHotkeys, 2000
FindNewHotkeys:
Loop, %A_ScriptDir%\*
{
RegExMatch(A_LoopFileName, "^(.)(.).ahk$", hk)
If (hk)
{
Hotkey, ~%hk1% & ~%hk2%, HotkeyLabel
}
}
Return
HotkeyLabel:
RegExMatch(A_ThisHotkey, "~(.) & ~(.)", hk)
run, %hk1%%hk2%.ahk
Return
#Persistent
SetTimer, FindNewHotkeys, 2000
FindNewHotkeys:
Loop, %A_ScriptDir%\*
{
RegExMatch(A_LoopFileName, "^(.)(.).ahk$", hk)
If (hk)
Hotkey, ~%hk1% & ~%hk2%, HotkeyLabel
}
Return
HotkeyLabel:
MsgBox, A hotkey has been pressed!
Return
I am not sure how to start this one. I went through the help files of AHK with no result.
I need to establish a construct like this (this is not in either UNIX shell or in AHK scripting language. Just shows the idea I am after)
while true
do
gosub screenscrape
; here, all text on page is on clipboard
; variable "input" is a predefined portion of the clipboard
case $input in
string-1)
gosub subroutione1;;
string-2)
gosub subroutine2;;
...
*)
echo "not found"
sleep 1minute
done
to make the things more complex, the parts noted as string-1, through string-n are also variables, read in from few different files, depending on time of the day or by trigger from an event.
can someone point me to the right direction for this ?
Autohotkey does not have any case statements. What everyone does is to use if and else statements. (I know how it feels. I like case, too)
A few tips for you:
You can't have that $ or a - in your variable name in autohotkey
...but you CAN have an underscore.
You don't need to terminate your lines with a ;.
Here is a translation into autohotkey for you.
gosub screenscrape
; here, all text on page is on clipboard
; variable "input" is a predefined portion of the clipboard
if(string1){ ;if the variable is not blank it will evaluate to `true`
gosub subroutine1
}else if(string2){
gosub subroutine2
}else{
msgbox not found
sleep 60000 ;milliseconds
}
Also, you can use real functions in autohotkey - you don't have to rely on gosubs. If you use gosubs, make sure you place a return at the end of them. You should also read the autohotkey docs concerning the "auto execute" section.