PDA

View Full Version : Using MsBox within a Periodic Function (don't)



dcromley
22-11-2011, 00:16
Hello, (probably Petr?)

I have used "MsgBox" often for debugging.
Have you ever issued a "MsgBox" within a TBGL Periodic Function?
It's not the thing to do. It piles up windows.

There's other ways to do what I want, but I thought I'd bother you
with this demo program anyway.

Option 1 is normal -- a 1000ms period and a routine that takes 200ms.
No problem

Option 2 has a 1000ms period and a routine that takes 2000ms.
I might have expected TBGL to start a 2nd instance of the routine
after 1000ms, before the 1st instance is done. But this doesn't
happen.

Option 3 has a 1000ms period and the routine issues a MsgBox.
TBGL starts new instances of the routine while the previous
instance is still waiting for a response. There can get to be "many"
windows open, but this demo is limited to 5.

I'm sure you know that you can cancel many open windows by
ending the "thinbasic.exe" process in the task manager.

If this is interesting, let me know what is going on. If it's not
interesting, my solution is to not issue a Msgbox.

Hoping I'm not a pest, Regards, Dave

Uses "Console", "UI", "TBGL", "Math"

Global hwnd, hfont As Long, iOpt As Long
Global gCount As Long

iOpt = InputBox$(0, "1 for 200ms, 2 for 2000ms, 3 for MsgBox")

hwnd = TBGL_CreateWindowEx("Esc to Exit", 1024, 768, 32, _
%TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow
TBGL_ResetKeyState()
hfont = TBGL_FontHandle("Courier New", 12)
TBGL_BuildFont(hfont) ' for print
TBGL_PeriodicBindFunction(hwnd, "TBGLLoop", 1000)
TBGL_ProcessPeriodicFunction(hwnd)
TBGL_DestroyWindow

Sub TBGLLoop()
If TBGL_GetWindowKeyOnce(hwnd, %VK_ESCAPE) Then
TBGL_PeriodicUnBindFunction(hwnd)
Exit Function
End If
TBGL_ClearFrame
TBGL_Camera(0,0,4, 0,0,0)
Incr gCount
If gCount = 5 Then
TBGL_PeriodicChangeInterval( hWnd, 60000) ' 1 minute
TBGL_PrintFont "Interval changed to 60sec. Hit CLOSE to end", 0,0,0
End If
Select Case iOpt
Case 1
DrawStuff1(gCount) ' normal, 200ms
Case 2
DrawStuff2(gCount) ' slow, 2000ms
Case 3
DrawStuff3(gCount) ' MsgBox
Case Else
TBGL_PeriodicUnBindFunction(hwnd)
Exit Function
End Select
TBGL_DrawFrame
End Sub

Sub DrawStuff1(num As Long) ' normal 200ms processing
Local hCWin As Long
DrawLine()
TBGL_PrintFont("Sleeping for 200ms; # " & num, 0,.2,0)
hCWin = Canvas_Window("Window", 100,100, 200,50)
Canvas_Attach(hCWin, 0)
Sleep 200
Canvas_Window End
End Sub

Sub DrawStuff2(num As Long) ' routine takes 2000ms
Local hCWin As Long
DrawLine()
TBGL_PrintFont("Sleeping for 2000ms; # " & num, 0,.2,0)
hCWin = Canvas_Window("Window", 100,100, 200,50)
Canvas_Attach(hCWin, 0)
Sleep 2000
Canvas_Window End
End Sub

Sub DrawStuff3(num As Long) ' routine issues MsgBox
Local hCWin As Long
DrawLine()
TBGL_PrintFont("Issuing MsgBox # " & num, 0,.2,0)
hCWin = Canvas_Window("Window", 100,100, 200,50)
Canvas_Attach(hCWin, 0)
MsgBox(0, "This is msgbox # " & num)
Canvas_Window End
End Sub

Sub DrawLine()
Local x, y, cosa, sina, ang As Single
ang = Frac(Timer/60)*2*Pi ' like a clock?
cosa = Cos(ang): sina = Sin(ang)
x = cosa - sina
y = sina + cosa
TBGL_Line(0,0,0, x,y,0)
End Sub

Petr Schreiber
22-11-2011, 10:22
Hi Dave,

thanks for interesting question.

I am afraid there is no general way to handle this msgbox case from within TBGL directly, the periodic function is implemented via timer, which just ticks and ticks and ticks... and the msgbox behaves like modeless window in this case.

But there is indeed one workaround possible. Before you display messagebox, you disable the periodic function, and after that you enable it again.

So this code:


MsgBox(hWnd, "This is msgbox # " & num)


Becomes this:


TBGL_PeriodicUnBindFunction(hwnd)
MsgBox(hWnd, "This is msgbox # " & num)
TBGL_PeriodicBindFunction(hwnd, "TBGLLoop", 1000)


Regarding problem when your application is spitting messageBoxes and you don't know how to kill it, there is possible solution too.
In case you are in development stage, and there is risk of msgbox overpopulation, always use Console module as well. Because Console has magic power - when you switch to console, and press Ctrl-C, it kills the program immediately.

I hope I answered your questions, let me know!


Petr

dcromley
22-11-2011, 18:19
Great! Thank you.