Iris Classon
Iris Classon - In Love with Code

AutoHotKey: hotstrings and sending input

Cheatsheet

Read below (after the cheatsheet) for details and examples.

Defining hotstring

::myHotstring:: myActionOrOutput

Hotstring options (some):

Options defined as

:option:myHotstring:: myActionOrOutput

:?: Triggers string inside another word

:c: Case sensitive

:c0: Not case sensitive

:k100: Key delay of 100 milliseconds. Does not work with SendIput

:r: Send as raw (not needed when using a continuation section)

Sending input

SendEvent – old release, used before as Send

Send – older release, used before SendInput. Accepts key delay

SendRaw – same as above, outputs {Enter} as text not key

SendInput – Faster and more reliable than Send.

SendInput {Raw} – same as above, outputs {Enter} as text not key

SendPlay – Works in many games where SendInput doesn’t work

ControlSend and ControlSendRaw – Sends to Window or Control

SendMode Input – defaults Send to SendInput

Other

::something::

(

          Text with Tab and  

          A new line  

)

Continuation section, preserves text as is, sent as raw (default)

Hotstrings are similar to hotkeys, but instead of keys we use strings to trigger an action. I’ve used hotstrings to quickly reply to emails, code snippets that work across editors, and in combination with sending both strings and key presses. Of course possibilities are endless.

Let’s have a look at the syntax.

To define a a hotstring we prefix the string with the :: deliminator, add the string and then the deliminator again. What happens between that and the return statement is up to you. For example

text =

(

Hi!

Let me have a think about this and I’ll get back to you tomorrow

Kind regards Iris Classon

)

::lmg::

SendInput %text%

SendInput !s

return

In the script above I define a variable called text, a variable is just something that represents something I assign to it, in this case the text between the two parentheses. The parentheses let’s me keep the formatting for the text, printing it as three lines of text instead of one. Since I’m combining a hotstring with some other actions I’ve decided to hold the text in a variable then send it, but you could also write:

::lmg::

(

Hi!

Let me have a think about this and I’ll get back to you tomorrow

Kind regards Iris Classon

)

Which is called a continuation section and will default the send method to raw. Or do a one liner (not defaulted to raw):

::lmg:: Let me get back to you

So what happens in the first example?

I’ve defined a hotstring, lmg , so when I type that and then hit enter or tab it prints the text, then (in my Mail client for Windows) sends Alt + s (! Is a modifier key that represents Alt, and by modifier key we mean a key that only affects the next key being pressed- which in this case is ‘s’) which is the mail client hotkey for sending the email.

Let’s talk about Send-something

This is where it can get a little bit confusing. We have five main ways of sending input:

Send

SendRaw

SendInput

SendPlay

SendEvent

Don’t get these confused with:

ControlSend and

ControlSendRaw

The last two I’ll cover at the end of this post.

Send and SendEvent are more or less the same, but older ways to send input – but reliability and speed is not as good as the other ways of sending input. Send sends input that will translate Send {Enter} to an enter key. SendRaw will however not translate, and instead sent it as is. However, a newer way of sending input is recommended, by using SendInput and SendPLay, which can modified to sending raw input by adding {Raw} (example: SendInput {Raw}.

SendEvent doesn’t have a {Raw} version, just because its old and rare, and you really shouldn’t use it anyway.

Actually, when you get a first script created for you during AHK installation you will see this at the top of the script:

#NoEnv

; Recommended for performance and compatibility with future AutoHotkey releases.

SendMode Input

; Recommended for new scripts due to its superior speed and reliability.

SetWorkingDir %A_ScriptDir%

; Ensures a consistent starting directory.

From what you can probably read from the comment below the SendMode Input we can simply refactor (clean up) the previous script to just use Send, as Input will be default. Input is default since a few releases ago, but adding those lines to the top of the script makes it more explicit as I’ve understood it. You can of course change that.

#NoEnv

SendMode Input

text =

(

Hi!

Let me have a think about this and I’ll get back to you tomorrow

Kind regards Iris Classon

)

::lmg::

Send {Raw} %text%

Send !s

return

Adding {Raw} there is not really needed, but I’ve left it there as a visual reminder for what it does- plus it is supposed to be faster.

A neat little trick I’ve used a few times is to use hotstrings for code snippets when I demo code, and I don’t want to depend on a certain editor and a code snippet plugin or extension. For added effect you can also add a key delay, which makes it look like the characters are being typed one by one. I’ve actually used that when recording videos as I don’t use audio overlay (I record audio as I demo), but you have to remember to turn of autocomplete in the IDE you are working on, or be ready for some surprises ;)

Here is an example:

; Default send mode is just Send and not SendMode Input

; This is due to SendInput and keydelay not working together, and SendPlay not liking

UAC

codeS1 =

(

function init() {  

    if (window.sqlitePlugin !== undefined) {  

        DAL.db = DAL.db || window.sqlitePlugin.openDatabase({ name: "mainDB.db" });  

    } else {  

        console.log("Could not open connection");  

    }  

};  

)

::s1::

SetKeyDelay, 120

Send {Raw} %codeS1%

return

Try for fun and see what happens if you do not add {Raw} – it would demonstrate quite clearly what it does. In short everything within the squiggly brackets is omitted as it tries to translate that into keys or other- which I can only assume it fails to do :) SetKeyDelay will add a slight delay between keys, so it seems like we are typing them at a fast but yet somewhat natural pace.

SendPlay is a bit tricky to explain. Basically it’s what you use to when certain games do not let you use SendInput due to gameguards (anti-cheating toolkits) or other reasons. It is able in some, but not all, games/programs to bypass that and stream the strokes as messages. I wish I could tell you exactly how it does that, but even after having a read in the source code I had to give up on that and just go by the documentation and the discussions in the forum in regards to how it works. To interrupt a SendPlay script you can use Ctrl + Esc, but be vary that you cannot do that with SendInput.

We aren’t quite done with hotstrings, let’s have a look at the strings themselves. You can define a few options for the hotstring, by adding an optional option in the middle of the first deliminator:

:here:MyHotString::

Here are some options:

:?: Will trigger when the string is inside another word

:c: Case sensitive

:c0: Not case sensitive

:k100: Key delay of 100 milliseconds. Does not work with SendIput

:r: Send as raw (not needed when using a continuation section as described earlier)

So the one-liner from earlier would require an uppercase G in lmG to work:

::lmG:: Let me get back to you

ControlSend and ControlSendRaw sends directly to a Window or Control. By now you know what Raw means so I’ll skip that. The best way to illustrate what these do, and hwo to use them is with this little example:

#s::

SetTitleMatchMode, 2

ControlSend, , (Get-Process Sea*).Name {Enter}, PowerShell

WindowKey + S will send the command (Get-Process Sea*).Name and then Enter-key to a Window that contains PowerShell in the name. The result of the PowerShell command is an iteration of all the processes that start with sea-in the name. Instead of piping I’m using member iteration to go through all of them, it’s speedier.

Well, I certainly haven’t covered everything- but a lot, so I’ll end the post here but expect more blog posts on AHK, and even some videos in the near future.

Comments

Leave a comment below, or by email.


Last modified on 2015-02-19

comments powered by Disqus