Beginners help. Variouse way's for sending/detecting key strokes

Helpful script writing tricks and HowTo's
User avatar
megnatar
Posts: 71
Joined: 27 Oct 2014, 20:49
GitHub: Megnatar
Location: The Netherlands

Beginners help. Variouse way's for sending/detecting key strokes

10 Nov 2015, 19:24

-------------------------A word from the author, Uhmm that would be me--------------------------
I've written this tutorial for those who having trouble sending key's and detecting mouse clicks and or key status And it's derived from my personal notes. I don't know it all so I might be wrong, and If I am. Please don't hesitate to correct me :D. All examples are working and use space bar as the trigger key with a message box/tooltip to show what you did. I expect this kind of tutorial to be posted already. But it never hurts to read a different view on the subject, so here goes.

You basically have all that you need when combining this tutorial with my application launcher script. Which will allow you to start any game and send key's/input to it's window.
Jump to: General Program Launcher

The manual that comes with ahk is very well written, I strongly suggest you read it, read it again and again!
Different situations ask for a different approach so be creative when writing you're script.

btw this tutorial is still work in progress and it might contain typo's, weird grammar (my native language is Dutch not English) and inconsistency's . I will correct those in future release.

--------------------------At the moment these subjects are covered--------------------------
The send command and it's variations.
Something about timing while sending key's
The KeyWait command, in less detail then send I might add.
A thing or two about variables and how they are evaluated.

Working examples for:
Single, double, key down status.
Repeating keystrokes using a while loop.
Triggering actions based on mouse position.
Toggle keys
Sending a different key with each key stroke.

--------------------------Send and it's variations--------------------------
A thing or two to know before using the send command. Send has a few build in modes to choose from, those will be:

- Input. Input is ahk's default for the send command and it's the quickest. It ignores SetKeyDelay.
- Event. Is less quick then input but I prefer to use it since it gives control over press duration and delay between the key's to send.
- Play. Good for sending long strings because it uses a buffer. Unfortunate nine out of 10 times useless in windows 7,8 and 10 thanks to UAC, even in full admin mode.
- Raw. Raw will send exactly what's written after the command, thats why it's raw :D. I never use it.

You can specifie the send mode to use at the top of a script using command:
SendMode, Input|Event|Play|InputThenPlay

Or you can call send command and its mode directly by using:
SendInput
SendEvent
SendPlay
SendRaw

If you write a script and want it to send it's key's to the window even when it's minimized or not active. You should use the ControlSend command.
ControlSend will also interfere the less of all send methods with user input, but it's slow.

--------------------------Timing is very important when sending--------------------------
Actually timing is very important when writing scripts in general.
When sending a key to a window you might take the following in to consideration:

- The total time it takes to send the key.
- The time it takes for the program you're sending it to, to complete it's action.

Sounds simple enough right?

Lets sketch a situation.
You send the 'W' key to some program and the action it takes for whatever W does takes 500ms to complete.
You use SendEvent and have SetkeyDelay set to 100ms delay and press duration of 50ms.
When you want the W key to repeat its action twice, then the following code will most likely fail.

Code: [Select all] [Download] GeSHi © Codebox Plus

SendEvent,{w down}{w up}{w down}{w up}


Why? Well PressDuration+TimeBetween sending key's takes a total of 150ms for one key stroke.
W key will be send twice to the program, but this SendEvent will take a minimum of 300ms to complete.
Since the second W down will be send a little after 150ms, the program you're sending it to is still busy completing it's first action.
You could solve this in two way's. The first is by sleeping between the send command.

Code: [Select all] [Download] GeSHi © Codebox Plus

SendEvent,{w down}{w up}		;150ms
sleep, 350 ;150+350=500ms
SendEvent,{w down}{w up}


The second method. You could temperately increase the keydelay and setting it back once the actions are done.

Code: [Select all] [Download] GeSHi © Codebox Plus

SetKeyDelay, 450, 50
SendEvent,{w down}{w up}{w down}{w up}
SetKeyDelay, 100, 50
return


--------------------------Double, Single, keydown--------------------------
Many way's to acomplish this. Here is one of the way's I do that.
I strongly advice against using SetTimer for sending key's because it will always wait to timeout before doing anything else.
The beauty of KeyWait is that it will not wait to timeout when specified state is reached.
When that state is reached KeyWait will set errorlevel to 0.

This means keywait will wait forever for space to be released before continuing.
KeyWait, space

This means keywait will wait forever for space to be pressed down before continuing.
KeyWait, space , D

This means keywait will wait 1 second for space to be released before continuing.
KeyWait, space , T1

Thus the D stands for Down, the T stands for Period/Time. T is in seconds but you can use a float.

A double, Single or keydown.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Using the above code on the left or right mouse button, would override the default action for the program you're sending to.
I advice against overriding the single click since it's probably slower than the programs native single click.
Instead you could use this code with the tilde ~ at the beginning of the Lbutton hotkey.
Tilde ~ tells the script not to block the native function of the key, thus retaining the programs original action.
The following code will be like a add-on.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



--------------------------About the while loop!--------------------------
I use the while GetKeyState("Space", "P") function in two way's. One using sleep, and will repeat the key to send.
The other using keywait, and is used to simulate keydown.

Repeating a keystrokes/commands using a while loop.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Holding space down to simmulate a other key down

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Last while loop example. This is something I actually use in RoboCraft.
I use it for my machine-gun(smg) bot and it gives me more accurate shooting.
The developers of that game simulated a recoil effect by lowering the accuracy when firing longer than +/- 1000ms(1second). Below code will pulsate firing.

If I explained everything well and you read my text properly then you should be able to understand which mouse click does what. I Use the Random command to randomize the sleep period between release and press key down again. This make the scripted hotkey harder to detect on the server side. You need to initiate the value's the first time the hotkey is fired, putting the Random commend below the keywait and its actions so it interferes the less waiting period.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


--------------------------Actions based on mouse position--------------------------
In this example a action is performed when moving the mouse along the X axes. There is lot of number joggling going on so I suggest switching SetBatchline, -1 on at the top
of you're script when using this. I used this to align camera's or getting pixel color and if red trigger some key. Here I replaced those things with a tooltip to display the numbers.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


--------------------------Toggle key--------------------------
Again many way's to toggle key's on or off. I find this method the best way for doing so.

Code: [Select all] [Download] GeSHi © Codebox Plus

Space::											;When space is pressed the first time, bAutorun is created and is empty.
If (bAutorun = "" ){ ;If bAutorun is blank, so it's holding no value. Do whatever comes below.
Msgbox Space is presed for the first time.`nSend, {w down} here.`n`nVariable bAutorun = %bAutorun%
bAutorun++ ;The ++ operator will increment the value in bAutorun by 1. bAutorun now hold the number 1. bAutorun+=1 would do the same.
}Else{ ;When above 'if' statement evaluates false, meaning the key was already pressed down once and that bAutorun holds 1.
Msgbox Space is presed for the second time.`nSend, {w up} again.`n`nVariable bAutorun = %bAutorun%
bAutorun = ;Delete whatever is in bAutorun. bAutorun is empty once more.
}
Return


--------------------------Looping through key's 1 by 1--------------------------
Sometimes its handy to have a single key pressing a different key with each key stroke.
Here with each press from space bar, key's 1, 2, 3, 4 ore 5 are send. Handy for triggering things like
skill one, skill two then skill three, etc, or Hitpoint Pot 1, 2, 3, 4 then 5 and so on.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

Last edited by megnatar on 07 Dec 2015, 13:59, edited 7 times in total.
Everything we call real is made of things that cannot be regarded as real!
N.Bohr.
There for:
I refuse to beliefe that. When you don't look at, or see the moon. It simply does not exist?
A. Einstein.

Really, that probebillity is true!
User avatar
megnatar
Posts: 71
Joined: 27 Oct 2014, 20:49
GitHub: Megnatar
Location: The Netherlands

Re: Beginners help. Variouse way's for sending/detecting key strokes

20 Nov 2015, 10:24

Indeed, for those who don't want to learn. but that was not the aim this tut.

Nice tool i must say.

Return to “Tutorials”

Who is online

Users browsing this forum: No registered users and 2 guests