Jump to content

Timers


GaryFrost
 Share

Recommended Posts

Only problem with this is it eliminates the ability to reuse a timer

I am not sure if i understand correct, but in what case we will need to reuse a timer?

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

  • Replies 41
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

I am not sure if i understand correct, but in what case we will need to reuse a timer?

Not sure it's just a functionality of the SetTimer

From MSDN

nIDEvent

[in] Specifies a nonzero timer identifier. If the hWnd parameter is NULL, and the nIDEvent does not match an existing timer then it is ignored and a new timer ID is generated. If the hWnd parameter is not NULL and the window specified by hWnd already has a timer with the value nIDEvent, then the existing timer is replaced by the new timer. When SetTimer replaces a timer, the timer is reset. Therefore, a message will be sent after the current time-out value elapses, but the previously set time-out value is ignored. If the call is not intended to replace an existing timer, nIDEvent should be 0 if the hWnd is NULL

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Updated: see 1st post for examples and include file, callback is handle and ptr is handled in the UDFs.

Just need to make sure the function that the callback is going to use takes 4 variables: "Func FunctionNamePassedToUDF($hWnd, $Msg, $iIDTimer, $dwTime)"

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Another Example updating statusbar every second:

#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <Timers.au3>
#include <GuiStatusBar.au3>

Global $iMemo, $hStatusBar

_Example_CallBack()

Func _Example_CallBack()
    Local $hGUI, $iTimer1, $iTimer2, $btn_change, $iWait = 3000
    Local $aParts[3] = [75, 150, -1]

    $hGUI = GUICreate("My Timers Using CallBack Function(s)", 400, 320)
    $iMemo = GUICtrlCreateEdit("", 2, 32, 396, 226, BitOR($WS_HSCROLL, $WS_VSCROLL))
    GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
    $btn_change = GUICtrlCreateButton("Change", 155, 275, 90, 20)
    $hStatusBar = _GUICtrlStatusBar_Create($hGUI, $aParts)
    _GUICtrlStatusBar_SetText($hStatusBar, @TAB & @TAB & StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC), 2)
    GUISetState()

    $iTimer1 = _Timer_SetTimer($hGUI, 1000, "_UpdateStatusBarClock") ; create timer
    $iTimer2 = _Timer_SetTimer($hGUI, 3000, "_TimerCallBackFunc2") ; create timer

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $btn_change
                If $iWait = 3000 Then
                    $iWait = 250
                Else
                    $iWait = 3000
                EndIf
                $iTimer2 = _Timer_SetTimer($hGUI, $iWait, "_TimerCallBackFunc2", $iTimer2) ; reuse timer with different interval
        EndSwitch
    WEnd
    ConsoleWrite("Killed Timer? " & _Timer_KillTimer($hGUI, $iTimer1) & @LF)
    ConsoleWrite("Killed Timer? " & _Timer_KillTimer($hGUI, $iTimer2) & @LF)
    GUIDelete()
EndFunc   ;==>_Example_CallBack

Func _UpdateStatusBarClock($hWnd, $Msg, $iIDTimer, $dwTime)
    _GUICtrlStatusBar_SetText($hStatusBar, @TAB & @TAB & StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC), 2)
EndFunc   ;==>_UpdateStatusBarClock

Func _TimerCallBackFunc2($hWnd, $Msg, $iIDTimer, $dwTime)
    MemoWrite("_TimerCallBackFunc2 Timer " & $iIDTimer & " Fired")
EndFunc   ;==>_TimerCallBackFunc2

; Write a line to the memo control
Func MemoWrite($sMessage)
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Well I guess I don't need to make it anymore. :P

Any chance this will get official include status?

I would suspect that the first thing that will have to happen is a new UDF will have to be created and tested. That process can take a while. :)

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

I would suspect that the first thing that will have to happen is a new UDF will have to be created and tested. That process can take a while. :)

Actually I cleaned up the code, re-did the examples and created a few new examples.

Committed the code.

Should be in the next beta.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

I mean I see the possibilities, but if you have a function with an endless while loop then it will just get stuck in the loop and not execute any of the other timers :-/ I mean I guess you don't need a while loop since it is called every x number of seconds but still.

That's called poor scripting and can happen easy enough with-out timers.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Well I mean I was hoping for a small type of multithreading :D I guess I was wrong.

Well it doesn't matter if you have some other loop other than in the callback function it should work.

For example the main loop doesn't stop the callbacks from happening. WM_TIMER events shouldn't rely on whether you have a loop someplace else.

And you know better than multi-threading, not going to happen in the current version of AutoIt.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Well it doesn't matter if you have some other loop other than in the callback function it should work.

For example the main loop doesn't stop the callbacks from happening. WM_TIMER events shouldn't rely on whether you have a loop someplace else.

And you know better than multi-threading, not going to happen in the current version of AutoIt.

I know but I can always dream :D

Link to comment
Share on other sites

  • 2 weeks later...

Nice work (as usual), Gary! :D

Just a minor note regarding the use of _Timer_ArrayDelete()... I think it probably isn't really necessary. For _Timer_KillAllTimers(), you don't really need to delete anything in the array. Simply freeing all the callbacks in the loop, then resizing the entire array outside of the loop is sufficient, like so:

Func _Timer_KillAllTimers($hWnd)
    Local $iResult, $hCallBack = 0
    For $x = 1 To $_Timers_aTimerIDs[0][0]
        If Not IsHWnd($hWnd) Then
            $iResult = DllCall("user32.dll", "int", "KillTimer", "hwnd", $hWnd, "int", $_Timers_aTimerIDs[$x][1])
        Else
            $iResult = DllCall("user32.dll", "int", "KillTimer", "hwnd", $hWnd, "int", $_Timers_aTimerIDs[$x][0])
        EndIf
        If @error Then Return SetError(-1, -1, False)
        $hCallBack = $_Timers_aTimerIDs[$x][2]
        If $hCallBack <> 0 Then DllCallbackFree($hCallBack)
    Next
    Global $_Timers_aTimerIDs[1][3]
    Return $iResult <> 0
EndFunc;==>_Timer_KillAllTimers

As for _Timer_KillTimer(), you can also get rid of the bulk of the _ArrayDelete() code, since you can make assumptions about the array, like this:

Func _Timer_KillTimer($hWnd, $iTimerID)
    Local $iResult, $hCallBack = 0, $iUBound = $_Timers_aTimerIDs[0][0]
    For $x = 1 To $iUBound
        If $_Timers_aTimerIDs[$x][0] = $iTimerID Then
            If Not IsHWnd($hWnd) Then
                $iResult = DllCall("user32.dll", "int", "KillTimer", "hwnd", $hWnd, "int", $_Timers_aTimerIDs[$x][1])
            Else
                $iResult = DllCall("user32.dll", "int", "KillTimer", "hwnd", $hWnd, "int", $_Timers_aTimerIDs[$x][0])
            EndIf
            If @error Then Return SetError(-1, -1, False)
            $hCallBack = $_Timers_aTimerIDs[$x][2]
            If $hCallBack <> 0 Then DllCallbackFree($hCallBack)

            For $i = $x To $iUBound - 1
                $_Timers_aTimerIDs[$i][0] = $_Timers_aTimerIDs[$i + 1][0]
                $_Timers_aTimerIDs[$i][1] = $_Timers_aTimerIDs[$i + 1][1]
                $_Timers_aTimerIDs[$i][2] = $_Timers_aTimerIDs[$i + 1][2]
            Next
            ReDim $_Timers_aTimerIDs[$iUBound][3]

            $_Timers_aTimerIDs[0][0] -= 1
            ExitLoop
        EndIf
    Next
    Return $iResult[0] <> 0
EndFunc;==>_Timer_KillTimer

Granted, the hard-coded nature of that for inner for loop is a bit ugly, but if you want, you can always calculate the subitem count on the first line of the function and use a for loop inside of that inner for loop. The point is that you're using $_Timers_aTimerIDs internally only, so it will be a 2D array with at least one row (that first row containing the item count). Error checking (which is the only thing borrowing the entire _ArrayDelete() function would sorta bring) would be kinda useless anyway, since the snippets throughout the UDFs assuming element [0][0] to be existent or that it is some valid integer might break too (with or without the _ArrayDelete() code checking for errors) ;)

Edit: Uh, I'm still messing with using timers in a script I'm using, but haven't yet fully integrated it, so I can't say for sure whether I did or didn't break anything in these pieces of code. Regardless, the gist of idea is there: having the full _ArrayDelete() code included in the UDF is entirely unnecessary :P

Edit: Oh, by the way, the description for _Timer_SetTimer() is incorrect... unless it does destroy timers? ;D

Edit: I just noticed that in _Timer_SetTimer(), you're not handling case where a specified $iTimerID <> -1 doesn't exist in the array. In such a case, $iResult is not going to be an array, so obviously, trying to return $iResult[0] is going to cause errors. At the least, $iResult should be declared as a 1-element array at the top of the function, but ideally, if the function doesn't find a matching $iTimerID, it should go ahead and create it for the user.

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

  • 1 month later...

Hi Gary,

You removed your timers.au3 function, will be available for the upcoming release of Autoit? But the latest version is still 3.2.10.0 and not 3.2.11.0 yet.

Get Current beta. It's 3.2.11.0.

Beta Thread at: http://www.autoitscript.com/forum/index.php?showtopic=19717

Beta Download at http://www.autoitscript.com/autoit3/files/beta/autoit/

My little company: Evotec (PL version: Evotec)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...