Page 1 of 2
Background running procedure
Posted: Sun Mar 07, 2010 2:50 pm
by charvista
I would like to run a procedure in background, for example a clock, since I cannot imagine a clock being stopped
So far, I have in the event loop a #PB_Event_Timer, but when you click on the menubar of this application, the clock stops.
I would like to make it running forever, uninterrupted. How do I do that ?
Snippet of what I have so far:
Code: Select all
Win = OpenWindow(#PB_Any, 0, 100,500, 300, "App" )
AddWindowTimer(Win,111,1000)
TextGadget(1,300,10,500,20,"")
BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
MenuTitle("Databases")
MenuItem(0001, "Database1s"+Chr(9)+"Ctrl+T")
MenuItem(0009, "Database2"+Chr(9)+"Ctrl+Y")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Timer
If EventTimer()=111
SetGadgetText(1,FormatDate("%hh:%ii:%ss",Date()))
EndIf
Case #PB_Event_CloseWindow
ExitEventLoop = #True
EndSelect
Until ExitEventLoop
Re: Background running procedure
Posted: Sun Mar 07, 2010 3:18 pm
by RASHAD
Hi charvista
Very quick snippet
Code: Select all
Procedure YourProcedure(*Value)
Repeat
SetGadgetText(1,FormatDate("%hh:%ii:%ss",Date()))
Delay(50)
ForEver
EndProcedure
Win = OpenWindow(#PB_Any, 0, 100,500, 300, "App" )
AddWindowTimer(Win,111,1000)
TextGadget(1,300,10,500,20,"")
BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
MenuTitle("Databases")
MenuItem(0001, "Database1s"+Chr(9)+"Ctrl+T")
MenuItem(0009, "Database2"+Chr(9)+"Ctrl+Y")
Thread = CreateThread(@YourProcedure(), *Value)
Repeat
Event = WaitWindowEvent()
Select Event
; Case #PB_Event_Timer
; If EventTimer()=111
; SetGadgetText(1,FormatDate("%hh:%ii:%ss",Date()))
; EndIf
Case #PB_Event_CloseWindow
ExitEventLoop = #True
EndSelect
Until ExitEventLoop
Re: Background running procedure
Posted: Sun Mar 07, 2010 3:46 pm
by charvista
CreateThread() is perfect. Your very quick example worked very well Rashad. Many thanks!
Re: Background running procedure
Posted: Sun Mar 07, 2010 4:09 pm
by ts-soft
Code: Select all
Procedure TimerCB(hWnd, uMsg, idEvent, dwTime)
If idEvent = 111
SetGadgetText(1, FormatDate("%hh:%ii:%ss", Date()))
EndIf
EndProcedure
Win = OpenWindow(#PB_Any, 0, 100, 500, 300, "App" )
;AddWindowTimer(Win, 111, 1000)
SetTimer_(WindowID(Win), 111, 1000, @TimerCB())
TextGadget(1, 300, 10, 500, 20, "")
BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
MenuTitle("Databases")
MenuItem(0001, "Database1s" + Chr(9) + "Ctrl+T")
MenuItem(0009, "Database2" + Chr(9) + "Ctrl+Y")
Repeat
Event = WaitWindowEvent()
Select Event
; Case #PB_Event_Timer
; If EventTimer() = 111
; SetGadgetText(1, FormatDate("%hh:%ii:%ss", Date()))
; EndIf
Case #PB_Event_CloseWindow
ExitEventLoop = #True
EndSelect
Until ExitEventLoop
KillTimer_(WindowID(win), 111)
Re: Background running procedure
Posted: Sun Mar 07, 2010 4:30 pm
by charvista
Hi Thomas (ts-soft)
Ah, you have a different way, using API's... It's good to know how to do that. Thank you, but when comparing your code and Rashad's, I will take Rashad's for two reasons:
1) CreateThread() is an internal PB function
2) and the main reason is that with your code the TextGadget is flickering, while Rashad's does not...
Re: Background running procedure
Posted: Sun Mar 07, 2010 4:44 pm
by ts-soft
charvista wrote:
1) CreateThread() is an internal PB function
If you require it for other os, you are right
charvista wrote:
2) and the main reason is that with your code the TextGadget is flickering, while Rashad's does not...
i can't see any flickering, i see only my version requires less cpu-usage
greetings
Thomas
Re: Background running procedure
Posted: Sun Mar 07, 2010 5:00 pm
by charvista
charvista wrote:2) and the main reason is that with your code the TextGadget is flickering, while Rashad's does not...
i can't see any flickering, i see only my version requires less cpu-usage

Well, I do... very clearly, without glasses

Re: Background running procedure
Posted: Mon Mar 08, 2010 3:38 am
by SFSxOI
ts-soft's version does not flicker here, works well.
Re: Background running procedure
Posted: Mon Mar 08, 2010 12:48 pm
by Baldrick
ts-soft's function looks good to me & is only being called 1 time every 1000ms, I can't see how this could possibly flicker?
Re: Background running procedure
Posted: Mon Mar 08, 2010 1:24 pm
by Trond
Rashads' code flickers a bit here.
Re: Background running procedure
Posted: Mon Mar 08, 2010 2:54 pm
by Mahan
Hmm, SetGadgetText() from within a thread, is that really ok?
Unless SetGadgetText() does some kind of synchronization in the background this looks pretty dangerous to me. (Long ago I did the equivalent of this in Delphi which resulted in random program crashes.)
Re: Background running procedure
Posted: Mon Mar 08, 2010 3:12 pm
by srod
It is fine providing the main process is running an event loop and thus retrieving messages etc. Personally, if using a thread, I'd be tempted to create the text gadget itself in the thread.
Re: Background running procedure
Posted: Mon Mar 08, 2010 4:38 pm
by charvista
Regarding the flickering, I had only this flickering on a Vista machine. On my Win7 both Rashad and ts-soft are perfect. The flickering is just the refreshing of the text.
I have encountered problems with Threads with StartDrawing() where I believe there is a conflict between the drawing in the normal program and the drawing in the thread. I'll post an example tomorrow as I don't have the code here.
Be ready to find a solution!

Re: Background running procedure
Posted: Mon Mar 08, 2010 4:40 pm
by srod
Both perfect here on Vista.
Re: Background running procedure
Posted: Tue Mar 09, 2010 12:49 pm
by charvista
Then maybe my Vista computer is too slow.
But now the problem I promised yesterday.
I made a small program that shows a clock running in background using CreateThread(). When you start the program all is going fine. But when you click on the menu File/Mayan Date Countdown it will open a new window with his own CreateThread() counting down the number of seconds until 21st December 2012, the famous "End of the Mayan Era". I had to add a KillThread() in the main window, otherwise the countdown window won't work. My goal is of course that both windows are running (clock & countdown) as BACKGROUND operation.
Either I don't know how to do that, or there is probably a conflict between the StartDrawing() of both operations.
I tried to keep the code as small as simple as possible.
Code: Select all
Declare zMayanDateCountDown(*Interval)
;StartEnumeration
Enumeration
#Font_1
#Image_1
#Image_2
#Image_11
#Image_12
#Gad_Image_1
#Gad_Image_11
EndEnumeration
;EndEnumeration
Procedure zMaya(ParentWin)
DisableWindow(ParentWin, 1)
Win1=OpenWindow(#PB_Any,0,0,400,300,"Mayan Date Countdown",#PB_Window_SystemMenu,WindowID(ParentWin))
h = LoadImage(#Image_11, #PB_Compiler_Home+"Examples\Sources\Data\terrain_texture.jpg")
ImageGadget(#Gad_Image_11, 0, 0, 400, 300, h)
DisableGadget( #Gad_Image_11, 1 )
CreateImage(#Image_12, 400,300)
Thread1 = CreateThread(@zMayanDateCountDown(), 50)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
ExitEventLoop = #True
;EndCase
EndSelect
Until ExitEventLoop
KillThread(Thread1) ; this line is okay since we leave the window
CloseWindow(Win1)
DisableWindow(ParentWin, 0)
EndProcedure
Procedure zClockText(Text.s)
StartDrawing(ImageOutput(#Image_2))
DrawImage(ImageID(#Image_1), 0, 0)
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#Font_1))
DrawText(150, 400, Text, $000000)
DrawText(147, 397, Text, $0000FF)
StopDrawing()
SetGadgetState(#Gad_Image_1, ImageID(#Image_2))
EndProcedure
Procedure zMayanText(Text.s)
StartDrawing(ImageOutput(#Image_12))
DrawImage(ImageID(#Image_11), 0, 0)
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#Font_1))
DrawText(50, 120, Text, $000000)
DrawText(47, 117, Text, $0000FF)
StopDrawing()
SetGadgetState(#Gad_Image_11, ImageID(#Image_12))
EndProcedure
Procedure zMayanDateCountDown(*Interval)
Repeat
Maya=Date(2012,12,21,0,0,0) ; Mayan Date assumed to be 21st Dec 2010, Time unknown, so midnight is assumed
Today=Date()
Remaining=Maya-Today
zMayanText(Str(Remaining))
Delay(*Interval)
ForEver
EndProcedure
Procedure zClock(*Interval)
Repeat
zClockText(FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",Date()))
Delay(*Interval)
ForEver
EndProcedure
;StartProgram -------------------------------------------------------------------------------------------------------------------
LoadFont(#Font_1,"Arial",50, #PB_Font_Bold)
UseJPEGImageDecoder()
Win = OpenWindow(#PB_Any, 0, 0, 1024, 600, "Applications", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
h = LoadImage(#Image_1, #PB_Compiler_Home+"Examples\Sources\Data\terrain_texture.jpg")
ImageGadget(#Gad_Image_1, 0, 0, 1024, 600, h)
DisableGadget( #Gad_Image_1, 1 )
CreateImage(#Image_2, 1024, 600)
BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
MenuTitle("File")
MenuItem(0001, "Mayan Date Countdown")
Thread = CreateThread(@zClock(), 50)
;EndProgram
;StartEventLoop ----------------------------------------------------------------------------------------------------------------------
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
ExitEventLoop = #True
Case #PB_Event_Menu
Select EventMenu()
Case 0001
KillThread(Thread) ;this line should not be there............ but it avoids conflicts... Solution???
; and due to the killthread, you cannot request it a second time
zMaya(Win)
;EndCase
EndSelect
;EndCase
EndSelect
Until ExitEventLoop
;EndEventLoop