|
Post by MrHiggins on Dec 17, 2021 7:53:42 GMT -5
Hi,
I have a little problem with this bit of code where I am using a timer and on the callback of the timer it just prints the time in milliseconds. I am finding that the application locks in place when trying to move the window using the titlebar. I have put a scan within the callback as the documentation mentions, but it does not seem to help?
open "graphics" for graphics as #g #g "trapclose [close]" timer 100, timerCallback wait
[close] timer 0 close #g end
sub timerCallback timer 0 scan #g "\"; time$("milliseconds") timer 100, timerCallback end sub
|
|
|
Post by tsh73 on Dec 17, 2021 8:19:12 GMT -5
Known bug. timer+sub+move window == freese
Cannot be helped as I can say (I've seen working code but I could not reliably reuse it in my program even looking at it)
On the other hand, using timer with [labels] works OK.
|
|
|
Post by Walt Decker on Dec 17, 2021 8:21:07 GMT -5
sub timerCallback timer 0 '<--- remove this scan #g "\"; time$("milliseconds") timer 100, timerCallback '<---- remove this end sub The event will return to the WAIT statement after the first TIMER statement.
EDIT:
Actually this is a serious bug. My fix does not work and on my machine using TIMER with a SUB locks the window. Should have been fixed many moons ago.
|
|
|
Post by Brandon Parker on Dec 17, 2021 8:55:54 GMT -5
sub timerCallback timer 0 '<--- remove this scan #g "\"; time$("milliseconds") timer 100, timerCallback '<---- remove this end sub The event will return to the WAIT statement after the first TIMER statement. Unfortunately, this does not resolve the problem. As Anatoly stated, there is a long-standing bug with the Timer when it is used with a Subroutine. You can use the Timer with the Label option with no issues; although, using Labels mixed with Subroutines/Functions presents its own challenges. You could try this option I worked up years ago... Multiple Timer RoutinesOr, you could check out how my Import Architect works. Import Architect Timer{:0) Brandon Parker
|
|
|
Post by MrHiggins on Dec 17, 2021 8:57:31 GMT -5
Thanks tsh73 and walt Decker I noticed that it seemed to work better using labels and had a feeling it could be a bug.
|
|
|
Post by Rod on Dec 17, 2021 9:03:09 GMT -5
The code still freezes with those changes. It can be done but as tsh73 states its not recommended.
nomainwin open "graphics" for graphics as #g #g "trapclose closedown"
while 1 call waitMilliseconds 500 #g "cls ; place 50 50" #g "\";time$("ms") scan wend
sub closedown h$ timer 0 close #g end end sub
sub waitMilliseconds ms timer ms, [stopWaiting] wait [stopWaiting] timer 0 end sub
The timer works perfectly well in a [branch] based coding structure. It gets problematic when we adopt a Sub coding structure. So this known bug that freezes the screen can be worked round. To do it the timer must be entirely encased in a sub of its own. Even then there is a danger the program flow gets hijacked at the scan or wait. Best not to mix [branch] and Subs in any case. For example your [close] branch will not be found if you click on close while it is in the timer Sub so a close Sub is needed.
|
|
|
Post by MrHiggins on Dec 17, 2021 9:16:35 GMT -5
Rod very nice fix, thank you very much
|
|
|
Post by Rod on Dec 17, 2021 13:45:47 GMT -5
Well it isn't really a fix it is a workaround and I would not use it other than in the simplistic demo I show. In a larger program using Subs the scope issues and multiple events will cause grief. So stick to a nice [branch] loop or be prepared to put the effort Brandon has put in to use API based timers.
|
|
|
Post by Brandon Parker on Dec 17, 2021 15:19:15 GMT -5
Another option would be to use a variation of the code shown below. It uses the Windows API, but has a lower learning curve that the API solution I linked to above.
Global uElapse1 : uElapse1 = 500 Global uElapse2 : uElapse2 = 1300 Global nlDEvent1, nlDEvent2, TimerProc1, TimerProc2 nlDEvent1 = 1 : nlDEvent2 = 2
CallBack TimerProc1, Test(ulong, ulong, ulong, ulong), void CallBack TimerProc2, Test2(ulong, ulong, ulong, ulong), void
NoMainWin WindowWidth = 270 WindowHeight = 150 StaticText #Test.timer1, "", 90, 25, 100, 25 StaticText #Test.timer2, "", 90, 75, 100, 25 Open "Window" For Window As #Test #Test "TrapClose Quit"
result = SetChangeTimer(Hwnd(#Test), nlDEvent1, uElapse1, TimerProc1) result = SetChangeTimer(Hwnd(#Test), nlDEvent2, uElapse2, TimerProc2)
While isWndOpen("#Test") Scan result = Sleep(1) Wend : End
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Sub Quit handle$ result = KillTimer(Hwnd(#handle$), nlDEvent1) result = KillTimer(Hwnd(#handle$), nlDEvent2) Close #handle$ End End Sub
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function Test(var1, var2, var3, var4) #Test.timer1 Time$() End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function Test2(var1, var2, var3, var4) #Test.timer2 Time$() End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function isWndOpen(handle$) On Error GoTo [Error] isWndOpen = Hwnd(#handle$) [Error] End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function Sleep(milliseconds) CallDLL #kernel32, "Sleep", milliseconds As ulong, _ ret As void End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function SetChangeTimer(hWnd, nlDEvent, uElapse, TimerProc) CallDLL #user32, "SetTimer", hWnd As ulong, _ nlDEvent As ulong, _ uElapse As ulong, _ TimerProc As ulong, _ SetChangeTimer As ulong End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function KillTimer(hWnd, nlDEvent) CallDLL #user32, "KillTimer", hWnd As ulong, _ nlDEvent As ulong, _ KillTimer As ulong End Function
{:0)
Brandon Parker
|
|