SetTimer - Func & Bind Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Albireo
Posts: 1756
Joined: 16 Oct 2013, 13:53

SetTimer - Func & Bind

04 Mar 2019, 11:42

I got some ideas about how to use SetTimer on this link .: SetTimer - different questions (very good idea at the end)

But I miss some more features, which I can't find the solution for.

Code: Select all

#Persistent
#SingleInstance Force

StopValue = 50
; MsgBox ,, Row %A_LineNumber% -> %A_ScriptName%, Return from MyTimer .: %Value% `nA_ThisLabel .: %A_ThisLabel%
First(StopValue)

Esc::ExitApp

First(StopTimer)
{	 fn := Func("MyTimer").Bind(A_ThisFunc, "123-321", StopTimer)
    SetTimer % fn
	 MsgBox ,, Row %A_LineNumber% -> %A_ScriptName%, Return from MyTimer .: %Value% `nA_ThisLabel .: %A_ThisLabel%
}

MyTimer(Func, y, StopTimer)
{	Value := 5*5
	Mem := A_ThisLabel
	If StopTimer > 25
	{	; SetTimer fn, off
		; SetTimer MyTimer, off
		; SetTimer MyTimer(,), Off
	}
	MsgBox ,, Row %A_LineNumber% -> %A_ScriptName%, Func .: %Func% `ny .: %y% `nValue .: %Value% `nA_ThisLabel .: %A_ThisLabel% `nMem := %Mem% `nStopTimer .: %StopTimer%
	Return %Value%
}
1.) I want to return a value from the "Timer" function - Is it possible?
2a.) Is the above timer only running once? (I don't need the variabel above StopTimer / StopValue?)
2b.) If not 2a. -Able to stop the timer (SetTimer MyTimer, off) in the timer "MyTimer" - Is it possible?
3.) The system variable A_ThisLabel / SetTimer never contains a value, why?
Albireo
Posts: 1756
Joined: 16 Oct 2013, 13:53

Re: SetTimer - Func & Bind

05 Mar 2019, 06:53

Made an attempt to solve my wishes...(however, is not entirely satisfied)
Spoiler
0.) A new question .:
How to create / start a timer object faster?
In the test-script it take almost 1/4 sec (on my computer) to activate the SetTimer object.
To handle this I have added an "unnecessary" delay, like this .:

Code: Select all

fn := Func("MyTimer").Bind(A_ThisFunc, "123-321", StopTimer)
SetTimer % fn, On
Sleep 250	; Allows to start SetTimer before next instruction
1.) The only way I found, to get a value from the Timer, was to make the variable Global, like this .:

Code: Select all

Global TimerStatus	; Possible to get a value from SetTimer
2.) Still unable to exit/stop the SetTimer in the timer object eg. SetTimer % fn, off ; Not possible to stop the SetTimer in the timer object. Outside the Timer object, it's no problem with .:

Code: Select all

SetTimer % fn, off
3.) Still don't know why the system variable A_ThisLabel / SetTimer never contains a value. Why?
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: SetTimer - Func & Bind

05 Mar 2019, 07:41

1) No. SetTimer is a command, not a function, and as such has no return value
The timer function is being called asynchronously, and as such there is no concept of a return value

2) No, because you did not specify a negative value for the timer. In fact, you specified no value at all, you just specified "On", so it just uses the default timing value of 250.

3) A_ThisLabel never holds anything because MyFunc is not a label, it is a function - A_ThisFunc would give you the name of the function

0) SetTimer does not fire the function immediately. If you specify a period of 250, the first fire of the function will be in 250ms
If you want the timer to fire immediately, just call the function when you set the timer.

Otherwise, I have no idea what you are trying to achieve.
If you want to explain it to me, I can probably show you how to achieve it.
Albireo
Posts: 1756
Joined: 16 Oct 2013, 13:53

Re: SetTimer - Func & Bind

05 Mar 2019, 10:09

Thanks for your time!
My wish is to handle a number of popup messages that can be displayed or not...
I want to use the same program for multiple purposes. The program I want to manage, handles products / article numbers.

As an example ..:
a.) Suppose the products I want to search for, should be in the database (existing products).
If the product I search for, is not found (error) - a popup message appear.
This message should be handled (be closed), and some information about that article/article number, should be saved in a logfile.
If the desired article number is found, the item is shown on the window (no problem - no popup message)

b.) Suppose the products I want to search for, should not be in the database (new products).
In this case, I always want to see the popup message "Product missing!".
If the article number is found, the popup message is not appear and the item is shown on the window (error - no popup message)

My idea was .:
1.) Search for an article number.
2.) Wait for the product or pop-up message to appear.
3.) Handle what should happens


But I must know if the popup message is closed by the timer. (There are some different popup messages that may occur).
___________________________________

0.) Is there anything else I missed? I still need Sleep 100 if I start the timer with SetTimer % fn, 1

Code: Select all

fn := Func("MyTimer").Bind(A_ThisFunc, "123-321", StopTimer)
SetTimer % fn, 1
Sleep 100	; Allows to start SetTimer before next instruction
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: SetTimer - Func & Bind

05 Mar 2019, 10:51

0)
A timer value of 1 will not fire every 1ms, it will fire every ~15ms (Due to minimum timer granularity)
As I said, SetTimer fires **for the first time** after the specified period. If you want to "fire it immediately", **just call what the timer would call**, like so:

Code: Select all

fn := Func("MyTimer").Bind(A_ThisFunc, "123-321", StopTimer)
SetTimer % fn, 1
MyTimer(A_ThisFunc, "123-321", StopTimer)
"If the product I search for, is not found (error) - a popup message appear." - What do you mean by this? The AHK script should create the popup, or the popup will appear as a result of what the AHK script does, and it needs to deal with it?

If you can create some mock code that gives me something to work with, I can maybe help further, but as it is, it's all a bit abstract to be able to come up with implementation suggestions
Albireo
Posts: 1756
Joined: 16 Oct 2013, 13:53

Re: SetTimer - Func & Bind

05 Mar 2019, 19:20

evilC wrote:
05 Mar 2019, 10:51
0)
A timer value of 1 will not fire every 1ms, it will fire every ~15ms (Due to minimum timer granularity)
As I said, SetTimer fires **for the first time** after the specified period. If you want to "fire it immediately", **just call what the timer would call**, like so:

Code: Select all

fn := Func("MyTimer").Bind(A_ThisFunc, "123-321", StopTimer)
SetTimer % fn, 1
MyTimer(A_ThisFunc, "123-321", StopTimer)
Yes!, the first call to "MyTimer" is now immediately, it seems to work as desired. :bravo:
evilC wrote:
05 Mar 2019, 10:51
"If the product I search for, is not found (error) - a popup message appear." - What do you mean by this?...
(I'll try to explain again).
a.) Suppose I want to process, already existing products in the program I want to work with.
eg. When an article number is entered into the search field of the program I want to control, I expect only one answer.
(several different answers can occur). Here I focus on two of the answers from the program I want to control .:
a1. - The expected answer .: The article number is found in the program I want to control, as answer product information is showed.
a2. - Not expected answer .: When the article number is NOT found in the program I want to control, an answer, a popup message is displayed with the information "The product could not be found! Should a new product be created?" (with the buttons Yes / No). In this case, my answer is No (the popup message from the program I want to control, disappears). After that some information, that the article number is not found, is saved in a log file.

A similar reasoning, as above, can be done if only new products are to be handled, but now I want to create new products instead.
evilC wrote:
05 Mar 2019, 10:51
If you can create some mock code that gives me something to work with, I can maybe help further...
Today I have an AHK program that handles some situations (with several thousand lines). But now I want to look over the whole structure, try to build with object, work with more modules (easier to complement functions / find problems and errors, etc.). Right now I'm trying to see if it is possible for me, to handle pop-up messages, using the SetTimer function. Under the "Spoiler" button is a rough structure of one part of the program.
Spoiler
The events I'm now trying to control are .:
Has the pop-up message "Product is missed!" been displayed / managed?
Has another pop-up message been displayed / managed?
Is the ItemNo found?
Is the search time over?

Now I can close the popup messages, using the SetTimer function (smoothly). But how to know that the message has been closed with the SetTimer and continue with the AHK program run? Can't get any results from "SetTimer" (and want to avoid Global variables)

Other things that do not feel perfect are eg. to write information to certain cells (eg the entry of article numbers to a field under the "Spoiler button" above), and a good object structure with field names etc.
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: SetTimer - Func & Bind

06 Mar 2019, 01:48

Albireo wrote: Can't get any results from "SetTimer" (and want to avoid Global variables)
An example:

Code: Select all

info := {counter: 0}
timer := Func("MyTimer").Bind(info)
SetTimer, % timer, 10
Sleep, 1000
MsgBox, % info.counter
Return

MyTimer(obj) {
   obj.counter++
}
Albireo
Posts: 1756
Joined: 16 Oct 2013, 13:53

Re: SetTimer - Func & Bind

06 Mar 2019, 04:00

Thanks!
It solved one desire.

Is it possible to stop the SetTimer if obj.counter >= 15?
Something like this (this doesn't work)

Code: Select all

MyTimer(obj) {
   obj.counter++
   If ( obj.counter = 15 )
      SetTimer % timer, off ; or SetTimer % timer, -100
}
The timer is stopped but the label doesn't exist
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: SetTimer - Func & Bind

06 Mar 2019, 05:45

I would not expect the timer to stop, as timer appears to be out of scope (Unless of course it is super-global)

Code: Select all

MyTimer(obj) {
   global timer
   obj.counter++
   If ( obj.counter = 15 )
      SetTimer % timer, off ; or SetTimer % timer, -100
}
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: SetTimer - Func & Bind  Topic is solved

06 Mar 2019, 05:56

Also note that if you want to stop a timer from within it's own function, you can do SetTimer, , Off

Code: Select all

MyTimer(obj) {
   obj.counter++
   If ( obj.counter = 15 )
      SetTimer, , off ; <-- Works as long as MyTimer was called by SetTimer
}
Albireo
Posts: 1756
Joined: 16 Oct 2013, 13:53

Re: SetTimer - Func & Bind

06 Mar 2019, 14:45

Thank you everyone! (I try to notice all the good answers, but I only manage to notice one answer - unfortunately!)
Summarizes the above with the following script

Code: Select all

#SingleInstance Force

oInfo := {Counter:0}
FuncTest(oInfo)
ExitApp

FuncTest(oInfoNo)
{	Timer := Func("MyTimer").Bind(A_ThisFunc, oInfoNo, "123-321")
	SetTimer % Timer, 10
	Sleep 1000
	MsgBox ,, Row %A_LineNumber% -> %A_ScriptName%, % oInfoNo.Counter
	Return
}

MyTimer(FuncName, oObj, StrInfo) {
	oObj.Counter++
	If ( oObj.Counter = 15 )
	{	SetTimer,, Off ; <-- Works as long as MyTimer was called by SetTimer
		MsgBox ,, Row %A_LineNumber% -> %A_ScriptName%, % "FuncName .: " FuncName "`noObj.Counter .: " oObj.Counter "`nStrInfo .: " StrInfo
	}
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], Thorlian and 164 guests