Jump to content

_Timer_SetTimer Troubles!


Recommended Posts

The app I'm working on needed a message notification area (a label) on my main GUI for presenting occasional info (usually an explanation for why a certain, say, button press wasn't currently allowed, that sort of thing). But after presenting the notification text, I want to hide that label after a few seconds so that the user doesn't think the problem is still in effect.

But the only way I could find to asynchronously hide the label was by using _Timer_SetTimer(), but it's not working as expected.  What's happening is that even though I call _Timer_KillAllTimers() when the timeout function is invoked, I keep getting timeout function calls over and over until my app crashes!  Can anyone help me figure out what I'm doing wrong?  Here's the relevant code snippets...

Func _MyNotifyMsg( $arg_Str )
    Local $Lf_Stat, $Lf_Error
    If $G_NotifyOn Then             ; If the last notification is still being shown
        _Timer_KillAllTimers( $MyGUI )
    EndIf
    $G_NotifyOn = True
    GUICtrlSetState( $L_NotificationsID, $GUI_SHOW )
    GUICtrlSetData ( $L_NotificationsID, $arg_Str )
    $Lf_Stat = _Timer_SetTimer($MyGUI, 2000, _MyNotifyMsgOff)
    $Lf_Error = @error
    _MyUpdStatusMsg("_MyNotifyMsg() - Timer Created -- @error = " & $Lf_Error)
    If $Lf_Stat = 0 Then                    ; Error creating timer..
        _MyUpdStatusMsg("_MyNotifyMsg() - ERROT creating Timer - @error = " & $Lf_Error)
    EndIf
    Return
EndFunc
;
;   =   =   =
;
Func _MyNotifyMsgOff( $hWndGUI, $MsgID, $iIDTimer, $iTime )
    #forceref $hWndGUI, $MsgID, $iIDTimer, $iTime
    _MyUpdStatusMsg("__MyNotifyMsgOff() invoked")
    GUICtrlSetData ( $L_NotificationsID, "" )
    _Timer_KillAllTimers( $MyGUI )
    $G_NotifyOn = False
    GUICtrlSetState( $L_NotificationsID, $GUI_HIDE )
EndFunc

Now, one big source of confusion regarding the _Timer_SetTimer call is whether or not to put quote marks around the name of the callback function. I've seen example posts calling it each way!  What's the right way?  I've tried it both ways, and neither way works as expected.  In any event, the code as posted above without quotes acts as follows: (1) The _MyNotifyMsg() call always works and never finds an error; (2): The _MyNotifyMsgOff() function also is correctly called, but weirdly the thing just keeps on being called even though another _MyNotifyMsg() func is never called; (3): Before long, the app crashes.

In other tests, when the first _MyNotifyMsgOff() callback function is invoked, the app crashes immediately!

Anyway, I can't help thinking if there was some way to, say, "de-register" the callback function, at least _MyNotifyMsgOff() wouldn't keep getting called repeatedly. But if you look at the Timers UDF, you see that the KillTimers calls invoke DllCallbackFree($hCallBack), so I have no idea why the callback func keeps getting callled...

Any advice, please?

 

ETA: By the way, I'm using On Event Mode in my app.

Edited by Mbee
Link to comment
Share on other sites

  • Moderators

Mbee,

Rather than get involved in the complexity of the _Timer UDF, I tend to use Adlib to hide labels after a short period of visibility - this example shows for 2 secs every 10 secs:

#include <GUIConstantsEx.au3>

Opt("GUIOnEventMode", 1)

$hGUI = GUICreate("Test", 500, 500)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

$cLabel = GUICtrlCreateLabel("", 10, 10, 200, 200)
GUICtrlSetBkColor($cLabel, 0xFFCCCC)
GUICtrlSetState($cLabel, $GUI_HIDE)

GUISetState()

$nBegin = TimerInit()

While 1

    Sleep(10)

    If TimerDiff($nBegin) > 10 * 1000 Then
        GUICtrlSetData($cLabel, "Initiated at " & @SEC)
        GUICtrlSetState($cLabel, $GUI_SHOW)
        AdlibRegister("_Hide_Label", 2000)
        $nBegin = TimerInit()
    EndIf


WEnd

Func _Hide_Label()
    AdlibUnRegister("_Hide_Label")
    GUICtrlSetState($cLabel, $GUI_HIDE)
EndFunc

Func _Exit()
    Exit
EndFunc

I think the code is self-explanatory, but please ask if you have any questions.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hey, Melba23, thanks for this great alternative!  I hadn't been aware of those functions, which will clearly do exactly waht I want. Thank Bob I don't have to mess around with timers anymore!

Wow, you're good!

All the best...

 

Link to comment
Share on other sites

4 minutes ago, Synapsee said:

anyway the _Timer_SetTimer problem is maybe from here :

; change that :
$Lf_Stat = _Timer_SetTimer($MyGUI, 2000, _MyNotifyMsgOff)
; for that :
$Lf_Stat = _Timer_SetTimer($MyGUI, 2000, "_MyNotifyMsgOff")

 

I understand that could be an issue, which is exactly why I wrote the following in my OP...

22 minutes ago, Mbee said:

Now, one big source of confusion regarding the _Timer_SetTimer call is whether or not to put quote marks around the name of the callback function. I've seen example posts calling it each way!  What's the right way

 

Link to comment
Share on other sites

  • Moderators

Mbee,

Glad you like it - as I said, I tend to avoid the Timer UDF as much as possible as I have always had trouble with it.

Quote

What's the right way

As shown in the Help file examples, you should use the function name as a literal string. However, in many cases where this is needed, it is also permissible to use the function as a first-class object - to do which you use the function name without quotes or trailing parentheses. In fact if you remove the quotes around the function name in the script I posted above you will see that it still functions.

The only advantage of which I am aware for using objects rather then literal strings is that Au3Stripper finds the line easier to digest - but no doubt there are others.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks for the enlightenment, Melba.  If in some unanticipated future I simply must use the Timer functions, I'll be better prepared.  But I hope that day never comes!

By the way, I've already implemented your Adlib algorithm in my Event Mode code, and it works like a charm!

Thanks again.

Edited by Mbee
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...