Autoit - timed key press

05/09/2012 16:57 maniack88#1
I'm trying to make a key press based on timer with on and off button

right now i'm facing a problem when, i press start, it will not send the key yet as it will wait the certain delay then only it will press the key

what i really need u guys help is, when i press start, it will send the key first, then it count the delay to repeat the key

here is the script

Code:
Global $timer_1, $timer_2, $timer_3, $timer_4, $timer_5, $timer_6, $timer_7
Global $script_running=0
Global $sleep=100 ;how long of a delay between running the script (100 = 10x / second)
Global $Delay_1 = 1000
Global $Delay_2 = 5000

WinActivate("Untitled - Notepad");
; Hotkeys
HotKeySet("{INSERT}", "start_script")
HotKeySet("{END}", "stop_script")


Func start_script()
        
        $timer_1=TimerInit()
        $timer_2=$timer_1
    $script_running = 1
EndFunc

Func stop_script()
    $script_running = 0
EndFunc

While 1
        
    If $script_running Then
        ;do stuff here
                If(TimerDiff($timer_1) >= $Delay_1) Then
                        Send ("2") ; 1 sec
                        $timer_1=TimerInit()
                ElseIf(TimerDiff($timer_2) >= $Delay_2) Then
                        Send ("3") ; 5 sec
                        $timer_2=TimerInit()
                Else
                        ;Send ("1")
                EndIf
        EndIf
        
        Sleep($sleep)
WEnd
appreciate u guys can advise a noob script kiddie here :)
05/09/2012 17:57 dumbfck#2
Well when you start the timer, you are straight away going into the main loop.
The first time you do TimerDiff($timer_1) the result will be 0. It will then continue to loop and repeat this test for 1 second before this condition is met:
Code:
If(TimerDiff($timer_1) >= $Delay_1) Then
If you change it to
Code:
If(TimerDiff($timer_1) <= $Delay_1) Then
Then the first time it tests this condition, TimerDiff($timer_1) will be 0 so it will be
Code:
If(0 <= 1000) Then
So the condition will be true.

However, you're going to have more problems because you then initialise timer_1 again, so you're always going to end up executing the code inside your first if(...) statement.

From what it looks like, you're trying to send a certain key sequence with specified delays between each key. Rather than use multiple timers for each delay, you might find it easier to make a sort-of 'state machine' where you use 1 timer but check for different values depending on which 'state' the program is in. This would be much easier to expand.
Something like this:
Code:
Global Const $_MAX_STATE = 5

Global $elapsedTime                ; running total of elapsed milliseconds
Global $state = 0                ; will be a value from 0 to however many stages you have
Global $waitForNextState = 1    ; so we don`t keep executing the current state every time around the loop

Global $times[$_MAX_STATE] = [0, 1000, 3000, 3500, 4800]    ; Delay from the start before next state
Global $keys[$_MAX_STATE] = ["2", "3", "1", "8", "6"]        ; value to print on each state

Global $timer_1 = TimerInit()
Global $diff = 0


While 1
    $diff = TimerDiff($timer_1)

    ; if we`ve reached the next state, reset $waitForNextState so we can pass the next condition
    if($diff > $times[$state] AND $waitForNextState = 0) Then
        $waitForNextState = 0
    EndIf

    ; if we`re at the time specified by the current state and we haven`t already printed this state`s output
    if($diff > $times[$state] AND $waitForNextState <> 0) Then
        ConsoleWrite($keys[$state] & @CRLF)
        $waitForNextState = 1    ; we`ve printed the output, so don't do it again until next state

        If $state < $_MAX_STATE-1 Then
            $state = $state + 1
        Else
            ; Reached the last state - reset state machine to 0
            $state = 0
            ; and reset timer
            $timer_1 = TimerInit()
        EndIf
    EndIf

    sleep(50)
WEnd
05/09/2012 18:29 amineurin#3
since autoit is a script language who run code line after line...so no multithread is possible...u can do it just simple by using the sleep function.

like:
keycode 1...
sleep(1000); 1 sec
keycode 2...
sleep(5000); 5 sec
or if defined time is needed use:
sleep($ur_defined_waittime_in_ms)

u also can use [Only registered and activated users can see links. Click Here To Register...] if u want to have a "function" who send the keycodes and call the function by a defined time.
the function repeats by ur defined time again and again.
to break it use adlibunregister.


maybe needfull if u try to spam the chat every 10 seconds, or better a random time :D
05/09/2012 21:44 dumbfck#4
The problem with:

keycode 1...
sleep(1000); 1 sec
keycode 2...
sleep(5000); 5 sec

is that the program can't do anything else useful in that sleep time. If it's literally a simple key sequence generator it's fine though.

With the state machine approach, you could technically put this inside your main loop which does a bunch of other stuff - this state checking / transition can be just a small part of the code.
05/09/2012 22:42 amineurin#5
yes, for that i wrote that autoit follow the code line by line.
so no other function while using sleep :)

i just wrote ways how it can be done.
since i dont really know what he like to program.
05/11/2012 20:37 maniack88#6
wow superb, i got the idea now thanks for helping amineurin and dumbfck!