Window Shake

You are aware that CallLater IS a method of the timer? And that AddHandler is the modern equivalent of GoTo, leading to spaghetti code and making it more difficult to follow? And why would you “loose control”? Does this sentence even make sense to you?

Doesn’t Timer.CallLater instantiate a new timer object every time it’s invoked? It’s not like you instantiate one specific timer and then call CallLater on it. How can “it” possibly be called “too many times”?

CallLater creates a call that sits “somewhere” in your app and you lose control. Except you use CancelCallLater, which could be confusing. Technically it’s the same as instantiating a timer manually with AddHandler, so it’s the same “spaghettish”. But you always know if there’s another execution coming up.
And if you want clear code, create a timer handler method that has the timer as the first parameter and you never have to guess what method is called by a timer.

Timer.CallLater (1000, addressof method)
Timer.CallLater (1000, addressof method)
Timer.CallLater (1000, addressof method)

This results in “method” will be called three times.
But
Timer.CancelCallLater (addressof method)
stopps all three.

Sure, that’s expected. But I’m not sure that that’s what @anon20074439 was referring to when he said “calling it too many times before the timer has a chance to run”.

Sorry, that is superstitious nonsense. CallLater doesn’t create a call that sits “somewhere” in your app and wants to jump you - it is a shared method of the timer class, and as with all shared methods you have to be aware of what that means.

As for loosing control, how is it different from starting a timer and letting it run autonomously and fire every 5 sec?

No. It’s less code, clearer code, plus you have control of the timing.

The example in the documentation even does exactly what Steve asked for:

Set the label with:

MyLabel.Text = "You entered your password incorrectly. Please try again."
Timer.CallLater(2000, AddressOf ClearLabel)

Clear the label with:

Sub ClearLabel
  MyLabel.Text = ""
End Sub

That’s it. Not even declaring or adding a timer is necessary.

I leave it to you to try and do that with AddHandler (including the timing) and argue which is cleaner code.

ClearLabel does what it’s name says, but what if we want to set the text after few seconds? And what if we want to do it for more than one label? Then we can’t hard code the text like we do in ClearLabel.

Now CallLater can only use ONE parameter, a variant. But we can use a class with all the properties we want to transfer all the info we want in that variant. We just have to use casting to get the properties out of the variant again.

So if you want to have more flexibility as to which label to update and when and change the text by sending a message to the label you can do it this way:

Add a new class cCourier (that delivers the target and message to the method: no super as it is an abstract class) to the app with the properties

Public Property Target As Label
Public Property Message As String

Add a method to the window:

Public Sub UpdateLabel(v as Variant)
  cCourier(v).Target.Text = cCourier(v).Message
End Sub

and use it like

Dim courier1 As New cCourier

courier1.Target = Label1
courier1.Message = "Label 1 got updated after 2 seconds"

Timer.CallLater(2000, AddressOf UpdateLabel, courier1)

Dim courier2 As New cCourier

courier2.Target = Label2
courier2.Message = "Label 2 got updated after 5 seconds"

Timer.CallLater(5000, AddressOf UpdateLabel, courier2)