Background running procedure
Re: Background running procedure
Works fine here if I remove the KillThread(). You have set the threadsafe compiler switch haven't you?
I may look like a mule, but I'm not a complete ass.
Re: Background running procedure
Based loosley around ur code Charvista & pretty rough, unchecked, etc, here is a version using Settimer_()
Code: Select all
;StartEnumeration
Enumeration
#Win1
#Font_1
#Image_1
#Image_2
#Image_11
#Image_12
#Gad_Image_1
#Gad_Image_11
#TmrA
#TmrB
EndEnumeration
;EndEnumeration
Procedure zMayanDateCountDown()
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
StartDrawing(ImageOutput(#Image_12))
DrawImage(ImageID(#Image_11), 0, 0)
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#Font_1))
DrawText(50, 120, Str(Remaining), $000000)
DrawText(47, 117, Str(Remaining), $0000FF)
StopDrawing()
SetGadgetState(#Gad_Image_11, ImageID(#Image_12))
EndProcedure
Procedure zMaya(ParentWin)
Shared Tmr2
DisableWindow(ParentWin, 1)
Win1=OpenWindow(#Win1,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)
Tmr2 = SetTimer_(WindowID(#Win1),#TmrB,200,@zMayanDateCountDown())
EndProcedure
Procedure zClockText()
Text.s=FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",Date())
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
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")
tmr1=SetTimer_(WindowID(Win),#TmrA,200,@zClockText())
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
Select EventWindow()
Case Win
ExitEventLoop = #True
Case #Win1
If Tmr2
KillTimer_(WindowID(#Win1),#TmrB)
Tmr2=0
EndIf
CloseWindow(#Win1)
DisableWindow(Win,0)
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case 0001
zMaya(Win)
EndSelect
EndSelect
Until ExitEventLoop
If tmr1
KillTimer_(WindowID(Win),#TmrA)
EndIf
If Tmr2
KillTimer_(WindowID(#Win1),#TmrB)
EndIf
Re: Background running procedure
@srod
No, I hadn't set the threadsafe compiler option. This is the reason why it did not work. With this option checked and KillThread() removed it now works fine here too. Thank you for the solution!
@Baldrick
Your code works without the threadsafe option checked!
Thank you to you too for the solution!
@PB Team:
Because CreateThread() was new to me, as well the variants like KillThread(), I was not yet aware that there was a compiler option for that. And if I ever saw it before, I did not know what it was. Therefore, to help future users of PureBasic with Threads, I think it is a good idea to add a small reminder that the threadsafe option should be checked to avoid unexpected behaviour, on the CreateThread() help-page.
No, I hadn't set the threadsafe compiler option. This is the reason why it did not work. With this option checked and KillThread() removed it now works fine here too. Thank you for the solution!
@Baldrick
Your code works without the threadsafe option checked!

@PB Team:
Because CreateThread() was new to me, as well the variants like KillThread(), I was not yet aware that there was a compiler option for that. And if I ever saw it before, I did not know what it was. Therefore, to help future users of PureBasic with Threads, I think it is a good idea to add a small reminder that the threadsafe option should be checked to avoid unexpected behaviour, on the CreateThread() help-page.

- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
Re: Background running procedure
The Threads overview in the PB user manual discusses the Threadsafe compiler switch etc. You didn't read it carefully enough! 

I may look like a mule, but I'm not a complete ass.
Re: Background running procedure
Srod, I must admit that you are completely right! You just showed me the right page to read!!
Now I understand Threads much better.
It's written that one must be careful with threads... indeed I could jump to the past or be back to the future!!

Now I understand Threads much better.
It's written that one must be careful with threads... indeed I could jump to the past or be back to the future!!

- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
Re: Background running procedure
Hi charvista
Today I got some time to play with your code, may be it is too late
But late better than nothing
Today I got some time to play with your code, may be it is too late
But late better than nothing
Code: Select all
;StartEnumeration
Enumeration
#Font_1
#Image_1
#Image_2
#Image_11
#Image_12
#Gad_Image_1
#Gad_Image_11
EndEnumeration
;EndEnumeration
Procedure zClock(*Interval)
Repeat
StartDrawing(ImageOutput(#Image_2))
DrawImage(ImageID(#Image_1), 0, 0)
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#Font_1))
DrawText(150, 450,FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",Date()), $000000)
DrawText(147, 447,FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss",Date()), $0000FF)
StopDrawing()
SetGadgetState(#Gad_Image_1, ImageID(#Image_2))
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
StartDrawing(ImageOutput(#Image_12))
DrawImage(ImageID(#Image_11), 0, 0)
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#Font_1))
DrawText(50, 120, Str(Remaining), $000000)
DrawText(47, 117,Str(Remaining), $0000FF)
StopDrawing()
SetGadgetState(#Gad_Image_11, ImageID(#Image_12))
Delay(*Interval)
ForEver
EndProcedure
;StartProgram -------------------------------------------------------------------------------------------------------------------
LoadFont(#Font_1,"Arial",50, #PB_Font_Bold)
UseJPEGImageDecoder()
OpenWindow(0, 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)
CreateImage(#Image_2, 1024, 600)
BodyMenu = CreateMenu(#PB_Any, WindowID(Win))
MenuTitle("File")
MenuItem(0001, "Mayan Date Countdown")
OpenWindow(1,0,0,400,300,"Mayan Date Countdown",#PB_Window_SystemMenu|#PB_Window_WindowCentered|#PB_Window_Invisible,WindowID(0))
h1 = LoadImage(#Image_11, #PB_Compiler_Home+"Examples\Sources\Data\terrain_texture.jpg")
ImageGadget(#Gad_Image_11, 0, 0, 400, 300, h1)
CreateImage(#Image_12, 400,300)
Thread = CreateThread(@zClock(),50)
;EndProgram
;StartEventLoop ----------------------------------------------------------------------------------------------------------------------
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
If GetActiveWindow() = 1
HideWindow(1, 1)
Else
ExitEventLoop = #True
EndIf
Case #PB_Event_Menu
Select EventMenu()
Case 0001
HideWindow(1, 0)
;EndCase
EndSelect
;EndCase
EndSelect
Until ExitEventLoop
;EndEventLoop
Egypt my love
Re: Background running procedure
Hi Rashad
Never too late to learn
Cool, you centered the Mayan countdown window and gave the ability to close the main window while the Mayan window is still open.
I wrote this program to understand the concept of background running programs.
In my apps, it is a bit more complicated. As my goal is to display a running clock in every window that the user opens in the right lower corner (like Windows), I have a global array to bring some data to each zClock(), because the Thread can enter ONLY ONE integer variable, and that's not enough. I need at least two. So my next question is:
How can I know in which application level I am now?
The procedure with the menu is always level 0. When making a choice from the menu, another procedure is called, that's level 1. If this procedure calls another procedure, it becomes level 2 and so on.
If I have a level number, then my global array can be a two-dimensioned array Array(Level, 0)=value1 and Array(Level,1)=value2.
I thought I could get the window handle given by #PB_Any when doing a Win=OpenWindow(#PB_Any,...) but it returns a too large and random number...
Any ideas?
Never too late to learn

Cool, you centered the Mayan countdown window and gave the ability to close the main window while the Mayan window is still open.
I wrote this program to understand the concept of background running programs.
In my apps, it is a bit more complicated. As my goal is to display a running clock in every window that the user opens in the right lower corner (like Windows), I have a global array to bring some data to each zClock(), because the Thread can enter ONLY ONE integer variable, and that's not enough. I need at least two. So my next question is:
How can I know in which application level I am now?
The procedure with the menu is always level 0. When making a choice from the menu, another procedure is called, that's level 1. If this procedure calls another procedure, it becomes level 2 and so on.
If I have a level number, then my global array can be a two-dimensioned array Array(Level, 0)=value1 and Array(Level,1)=value2.
I thought I could get the window handle given by #PB_Any when doing a Win=OpenWindow(#PB_Any,...) but it returns a too large and random number...
Any ideas?
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
Re: Background running procedure
charvista
Hi again
If you faced any problem just put some code,and the guys here will give you their best shots
But in case you will need more than one thread you have to learn how to CreateMutex() to sync. between
the different threads
I personaly like PureBasic Threads because I like to control what I am doing by myself
Threads has advantages and disadv. and so settime_() too it is not threadsafe class by itself
Beside it is controled by Windows so you will notice that there is a gap in time between your application
and the settime thread
You are going very fast charvista but be careful with your comments man,will you ?
Hi again
If you faced any problem just put some code,and the guys here will give you their best shots
But in case you will need more than one thread you have to learn how to CreateMutex() to sync. between
the different threads
I personaly like PureBasic Threads because I like to control what I am doing by myself
Threads has advantages and disadv. and so settime_() too it is not threadsafe class by itself
Beside it is controled by Windows so you will notice that there is a gap in time between your application
and the settime thread
You are going very fast charvista but be careful with your comments man,will you ?
Egypt my love
Re: Background running procedure
charvista
I think you can create thread with more than one variable
See next ,Try and give us your feedback
I think you can create thread with more than one variable
See next ,Try and give us your feedback
Code: Select all
Procedure RunThread(param_1,param_2,param_3,param_4)
;.......................
;.......................
;.......................
EndProcedure
Procedure zClock(Parameter)
Shared param_1.i,param_2.i,param_3.i,param_4.i
RunTread(x_1, x_2,x_3,x_4)
EndProcedure
;....................................
;....................................
;....................................
Thread = CreateThread(@zClock(), Parameter)
Egypt my love
Re: Background running procedure
Hi RASHAD
Sorry for the delay, I have been thinking about that all.
Your solution is smart -- using Shared variables.
After thinking and experiencing, I prefer to use global variables, these are also shared everywhere.
A global two-dimensioned array was the ideal solution to me.
Only problem was the procedure level to get because every window has his own values, for example #ImageGadget.
I found a solution.
Every time I do a OpenWindow(), I call zGetApp() then I fill the _AppValue() array with the necessary values
And this is the zGetApp() procedure:Then I can add a threadand when the window is going to be closed, I kill the thread and set the first value to 0 to free it to other windows
OK, I don't know if you understand this as this is rather complex, but it works. The variable App is the level number.
Edit: In my case CreateMutex() is not necessary, but I do understand the concept of the Mutex.
Sorry for the delay, I have been thinking about that all.
Your solution is smart -- using Shared variables.
After thinking and experiencing, I prefer to use global variables, these are also shared everywhere.
A global two-dimensioned array was the ideal solution to me.
Code: Select all
Global Dim _AppValue.i(100,1) ; Application, SubValue
I found a solution.
Every time I do a OpenWindow(), I call zGetApp() then I fill the _AppValue() array with the necessary values
Code: Select all
zGetApp(@App)
PokeI(*App,App)
_AppValue(PeekI(*App),0)=Image4 ; image number - will never be 0
_AppValue(PeekI(*App),1)=ImGad4 ; image gadget number
Code: Select all
Procedure zGetApp(*App.integer)
For i=1 To 100
If _BottomLine(i,0)=0
PokeI(*App,i)
Break
EndIf
Next
EndProcedure
Code: Select all
Thread=CreateThread(@zAppClock(), App)
Code: Select all
KillThread(Thread) : _BottomLine(App,0)=0
Edit: In my case CreateMutex() is not necessary, but I do understand the concept of the Mutex.
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
Re: Background running procedure
You sure that it's not enough? Only one integer variable is all we need, we only pass pointer to structured variable.charvista wrote:because the Thread can enter ONLY ONE integer variable, and that's not enough. I need at least two.
Here is one quick example:
Code: Select all
EnableExplicit
Debug "****** Program start! ******"
Structure variables_for_thread
first_variable.i
second_variable.i
third.b
fourth.s
fifth.c[10]
EndStructure
Procedure thread1(*struct.variables_for_thread)
Debug "*** Thread start! ***"
Debug *struct\first_variable.i
Debug *struct\second_variable.i
Debug *struct\third.b
Debug *struct\fourth.s
Debug *struct\fifth.c[0]
Debug *struct\fifth.c[1]
Debug *struct\fifth.c[2]
Debug *struct\fifth.c[3]
Define i
For i=3 To 9
Debug *struct\fifth.c[i]
Next
Debug "*** Thread end! ***"
EndProcedure
Define myvariables.variables_for_thread
myvariables\first_variable.i=5
myvariables\second_variable.i = 6
myvariables\third.b=1
myvariables\fourth.s="test string"
myvariables\fifth.c[0]=255
myvariables\fifth.c[1]=5
myvariables\fifth.c[2]=10
myvariables\fifth.c[3]=15
myvariables\fifth.c[5]=25
myvariables\fifth.c[8]=40
Define thread = CreateThread(@thread1(),myvariables)
WaitThread(thread)
Debug "****** Program end! ******"
Re: Background running procedure
Hmmm, interesting. Thanks for the idea, CAS.
I have to study this as I have never used structures before. Maybe it will simplify my solution even more.
I know PureBasic for 2 years now, but I really began using it for about 1 year.
After learning the basic language, how to draw pictures, write text on pictures, using floating numbers, memory pointers, threads, now I think it's time to look at the structures much closer. Seems it's powerful as it also use memory pointers.
And later the SQLite......
I have to study this as I have never used structures before. Maybe it will simplify my solution even more.
I know PureBasic for 2 years now, but I really began using it for about 1 year.
After learning the basic language, how to draw pictures, write text on pictures, using floating numbers, memory pointers, threads, now I think it's time to look at the structures much closer. Seems it's powerful as it also use memory pointers.
And later the SQLite......
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%