Example Application Code
-
- User
- Posts: 65
- Joined: Tue Feb 11, 2020 7:50 am
Example Application Code
Hello guys, I'm embarking my journey on PureBasic and want to ensure that I'm doing it the right way. I currently work with Golang, .NET C# for backend work and JS frontend such as Angular, React. First time with 'windows' GUI programming so I'm a bit lost. Dabbled with VB6 ages ago but nothing substantial back cuz I guess I was just a student.
So, Is there sample code for an entire application that I can take a look at? Preferably one that does something like below.
1. Main parent window with child windows opened from menu
2. Do something in the child window like create a record and save
3. Interact with other child windows - parent -> child, child->child etc. Update a label, change color.
Well, for that matter, anything to get my feet off the ground would be helpful.
I've looked at the example codes but it doesn't show me a structure of an app.
If anyone can help, it'll be much appreciated.
So, Is there sample code for an entire application that I can take a look at? Preferably one that does something like below.
1. Main parent window with child windows opened from menu
2. Do something in the child window like create a record and save
3. Interact with other child windows - parent -> child, child->child etc. Update a label, change color.
Well, for that matter, anything to get my feet off the ground would be helpful.
I've looked at the example codes but it doesn't show me a structure of an app.
If anyone can help, it'll be much appreciated.
Re: Example Application Code
1. Main parent window with child windows opened from menu
2. Do something in the child window like create a record and save
3. Interact with other child windows - parent -> etc
Hello lady,lesserpanda wrote: ↑Wed Nov 23, 2022 12:05 amI've looked at the example codes but it doesn't show me a structure of an app.
welcome !
So... Imagine that each example code is a brick. And you are asking << How could I build a home ? >>
It depends lots of things. There are little houses. There are huge castles. There are big building. Etc...
Coding is a little bit the same thing, but sure that, in coding, you can build a small roasted house, and its status will be very stable. But unable to add a little thing without breaking everything to the floor and code everything again.
However, if you build the first level of a building, with a big metallic skeleton, add new software features will be easy.
So 3 things :
1) look at multi document interface help page to check if this type of brick is for you.
2) look at How to build a DLL to discover the best way to let you an infinity of additionnal features to your software.
3) A interesting "mortar" to fix the bricks and to reduce the problems of compatibilities between several versions of your programs : help about maps
Waiting your first code try, and your technical questions to ease your coding life, have a good luck !
-
- User
- Posts: 65
- Joined: Tue Feb 11, 2020 7:50 am
Re: Example Application Code
Hello, thanks for your reply.
I have made a quick code below to open 2 child MDI window and tried to put a ListIconGadget in one of them however, it doesn't quite work. How do I add items in the child window? By the way, does indenting code make it part of the parent? Sorry for basic question
I have made a quick code below to open 2 child MDI window and tried to put a ListIconGadget in one of them however, it doesn't quite work. How do I add items in the child window? By the way, does indenting code make it part of the parent? Sorry for basic question
Code: Select all
Enumeration
#Window_Main
#Window_Child1
#Window_Child2
EndEnumeration
Enumeration
#Menu_Main
EndEnumeration
Enumeration
#Gadget_ChildWindows
EndEnumeration
Enumeration
#Button1
EndEnumeration
OpenWindow(#Window_Main, 0, 0, 400, 300, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
CreateMenu(#Menu_Main, WindowID(#Window_Main))
MenuTitle("Child Windows")
MDIGadget(#Gadget_ChildWindows, 0, 0, 0, 0, 0, 0, #PB_MDI_AutoSize)
AddGadgetItem(#Gadget_ChildWindows, #Window_Child1, "child window 1")
AddGadgetItem(#Gadget_ChildWindows, #Window_Child2, "child window 2")
ListIconGadget(#Button1, 10, 10, 150, 25, "Child Window Item", 100)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: Example Application Code
No problem. You have the medal #1 because you have understood my sentences, full of mistakes ! If nobody answers, I will bring anything in 10 hours.
And congratulations for this first code.
I recall what we need :
- record in child window (StringGadget())
- communication between windows (horizontal and vertical)
- List icon in a (child here) window
- check in the doc if MdiGadget can do a tree of windows.
Re: Example Application Code
Simple error: You start a new enumeration for your child windows, so the first elements of both enumerations have the same value. Just put the constants of your child windows into the first enumeration (that's why I always prefer dynamic ID generation):
Code: Select all
Enumeration
#Window_Main
#Window_Child1
#Window_Child2
#Gadget_ChildWindows
EndEnumeration
Enumeration
#Menu_Main
EndEnumeration
Enumeration
#Button1
EndEnumeration
OpenWindow(#Window_Main, 0, 0, 400, 300, "MDIGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
CreateMenu(#Menu_Main, WindowID(#Window_Main))
MenuTitle("Child Windows")
MDIGadget(#Gadget_ChildWindows, 0, 0, 0, 0, 0, 0, #PB_MDI_AutoSize)
AddGadgetItem(#Gadget_ChildWindows, #Window_Child1, "child window 1")
AddGadgetItem(#Gadget_ChildWindows, #Window_Child2, "child window 2")
ListIconGadget(#Button1, 10, 10, 150, 25, "Child Window Item", 100)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Re: Example Application Code
in my experience, a good structure of constants and naming of the same is essential for the survival of larger projects...
This is how I set up my object numbers. (You can do it this way, but you don't have to)
A good approach is the use of names in the enumerations.
Anyway, you need to know which objects are mapped in the same area, i.e. where the same object numbers get in each other's way. Or you use #PB_Any for dynamic creation.
This is how I set up my object numbers. (You can do it this way, but you don't have to)
A good approach is the use of names in the enumerations.
Anyway, you need to know which objects are mapped in the same area, i.e. where the same object numbers get in each other's way. Or you use #PB_Any for dynamic creation.
Code: Select all
Enumeration EWindow ; My Style: E stands for Enumeration !!! not necessary -- PB FormDesigner uses FormWindow
#WINDOW_Main
EndEnumeration
Enumeration EGadget
; on Main Window
#GADGET_TxtSearchWindow ; constant text, visible or hidden
#GADGET_TxtMousePos
#GADGET_TxtWndHandle
EndEnumeration
; = different file (i.e. included by XIncludeFile )
Enumeration EWindow
#WINDOW_Trace
EndEnumeration
Enumeration EGadget
; on Trace Window
#GADGET_Trace_LstOutput
#GADGET_Trace_BtnClear
#GADGET_Trace_BtnCopyToClipboard
; ; on Trace Window (second suggestion)
; #GADGET_LstOutput
; #GADGET_BtnClear
; #GADGET_BtnCopyToClipboard
EndEnumeration
Enumeration EMenu
#MENU_Main
EndEnumeration
Enumeration EMenuItem
#MENU_Main_File_Open
#MENU_Main_File_Save
#MENU_Main_File_SaveAs
#MENU_Main_File_Close
#MENU_Main_Edit_Undo
#MENU_Main_Edit_Redo
; etc.
EndEnumeration
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Re: Example Application Code
I m agree with Axolotl for this code part :This, because the menu items require several constants only. These constants must be so well named. And this name syntax example is easy to remember !
And I agree with jacdelad for the gadgets.
If the window contains permanent gadgets : constants using.
If the window contains gadgets which must be added and removed on the fly, by the final user, then generic using.
Code: Select all
Enumeration EMenuItem
#MENU_Main_File_Open
#MENU_Main_File_Save
#MENU_Main_File_SaveAs
#MENU_Main_File_Close
#MENU_Main_Edit_Undo
#MENU_Main_Edit_Redo
; etc.
EndEnumeration
And I agree with jacdelad for the gadgets.
If the window contains permanent gadgets : constants using.
If the window contains gadgets which must be added and removed on the fly, by the final user, then generic using.
Code: Select all
; generic using example : use of "#PB_Any"
myVariable = ButtonGadget(#PB_Any, x, y, w, h, text)
Re: Example Application Code
I completely agree with you.
I use fixed constants on permanent windows and dynamic numbers on so called "Requesters", which are created each time before they are displayed...
The nice thing about PB is that you have so many possibilities.
For beginners certainly sometimes a too large selection.
I use fixed constants on permanent windows and dynamic numbers on so called "Requesters", which are created each time before they are displayed...
The nice thing about PB is that you have so many possibilities.
For beginners certainly sometimes a too large selection.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Re: Example Application Code
Hi there and welcome
Every programmer has his own ways, and I am not sure if I am working the best way. For me the step to PureBasic was difficult in the beginning as I was not used to creating my own eventhandler.
When I create programs I usually do the following:
Most of the time I create forms with the form-generator and then include the .pbf-file.
I create a program with different files:
- a .pbp: the projectfile
- a number of include-files:
- Structures.pbi
- Procedures.pbi (sometimes split up)
- Specific .pbi-files when I have a number of procedures that have to do with the same subject; e.g. PDFModule.pbi, etc...
- a .pbf file for each window. I am quite lazy and draw the windows in de form-editor . I disable the 'Generate events procedure' because I do that in one central .pb-file.
- one central .pb-file (MainProgram.pb or something like that)
The central .pb-file starts with the following:
My projects are usually not really large and I am used working with variables and #PB_Any.
This means that if I connect to a database for example this looks as follows:
I would really teach yourself to be STRICT in closing connections to databases, freeing memory etc..
Hope this gives you a basis of insight in how I work.
Please be advised that I am definately not a programmer and if you look around you will learn a lot of the code you read on the forum
Regards,
Geert
Every programmer has his own ways, and I am not sure if I am working the best way. For me the step to PureBasic was difficult in the beginning as I was not used to creating my own eventhandler.
When I create programs I usually do the following:
Most of the time I create forms with the form-generator and then include the .pbf-file.
I create a program with different files:
- a .pbp: the projectfile
- a number of include-files:
- Structures.pbi
- Procedures.pbi (sometimes split up)
- Specific .pbi-files when I have a number of procedures that have to do with the same subject; e.g. PDFModule.pbi, etc...
- a .pbf file for each window. I am quite lazy and draw the windows in de form-editor . I disable the 'Generate events procedure' because I do that in one central .pb-file.
- one central .pb-file (MainProgram.pb or something like that)
The central .pb-file starts with the following:
Code: Select all
; Use-commands for having the right codes to do things
UsePostgreSQLDatabase()
UsePNGImageDecoder()
; Include the different forms
IncludeFile("Window1.pbf")
IncludeFile("Window2.pbf")
IncludeFile("Window3.pbf")
; Include the two main files
IncludeFile("Structures.pbi")
IncludeFile("Procedures.pbi")
; Here some main procedures that need to be run during startup
ReadSettings()
Blablabla()
OpenMainWindow() ; Name of the main window
; Here comes the part that took me quite some time to find out:
intQuit=0
Repeat
intEvt=WaitWindowEvent()
Select intEvt
Case #PB_Event_Gadget
Select EventGadget()
Case lst_BlablaList
If EventType()=#PB_EventType_LeftDoubleClick
OpenWindow1() ; Use a correct name for the window.. Window1 is a bad name ;)
ToonData() ; The procedure you want to run after the window is opened.
EndIf
Case btn_ThisAndThat
ThisAndThatProcedure()
EndSelect
Case #PB_Event_CloseWindow
Select EventWindow()
Case MainWindow
intQuit=1
Case Window1
CloseWindow(Window1)
Window1=0
Case Window2
CloseWindow(Window2)
Window2=0
EndSelect
EndSelect
Until intQuit=1
This means that if I connect to a database for example this looks as follows:
Code: Select all
db_Dataset=OpenDatabase(#PB_Any,DatabaseName,DatabaseUser,DatabasePassword)
DatabaseUpdate(db_Dataset,"USE Database1")
SetDatabaseLong(db_Dataset,0,int_Lookupdata)
DatabaseQuery(db_Dataset,"SELECT field1,field2,field3 FROM table WHERE id=$1")
While NextDatabaseRow(db_Dataset)
field1.s=GetDatabaseString(db_Dataset,0)
....
Wend
CloseDatabase(db_Dataset)
Hope this gives you a basis of insight in how I work.
Please be advised that I am definately not a programmer and if you look around you will learn a lot of the code you read on the forum
Regards,
Geert
-
- User
- Posts: 65
- Joined: Tue Feb 11, 2020 7:50 am
Re: Example Application Code
Hello everyone, and thanks for all the information.
Regarding database connections. I am doing it like this.
Database connection is opened and set as a Global Connection. I leave it open and run queries etc in procedures referencing the database connection.
Only at the end, when I capture the event to quit, then I close the database connection.
Is this ok to do? Or better to keep opening and closing the database connection in the procedures itself? Is there like a keep-alive for the database connections because the app will be just left open for days.
Regarding database connections. I am doing it like this.
Database connection is opened and set as a Global Connection. I leave it open and run queries etc in procedures referencing the database connection.
Only at the end, when I capture the event to quit, then I close the database connection.
Is this ok to do? Or better to keep opening and closing the database connection in the procedures itself? Is there like a keep-alive for the database connections because the app will be just left open for days.
Re: Example Application Code
I don't think, that your program make database actions all the time .... so you have to open and close it. Also if the db is not sqlite, the server can terminate the connection every time... you must always check it.lesserpanda wrote: ↑Fri Nov 25, 2022 12:13 am Hello everyone, and thanks for all the information.
Regarding database connections. I am doing it like this.
Database connection is opened and set as a Global Connection. I leave it open and run queries etc in procedures referencing the database connection.
Only at the end, when I capture the event to quit, then I close the database connection.
Is this ok to do? Or better to keep opening and closing the database connection in the procedures itself? Is there like a keep-alive for the database connections because the app will be just left open for days.
only one opendatabase call and one closedatabase call will not work
-
- User
- Posts: 65
- Joined: Tue Feb 11, 2020 7:50 am
Re: Example Application Code
Thank you for your insight. This has helped me alot in avoiding issues with DB.
Re: Example Application Code
When I ll find the time, I ll switch my computer on.
Note that an interesting rule being the way to name the variables in a source code... :
... can be applied for more flexible variables in a map.
It is a lil bit slower, but it is clever. More accurately, a dynamic map.
Note that an interesting rule being the way to name the variables in a source code... :
Code: Select all
GeneralMediumLocal
It is a lil bit slower, but it is clever. More accurately, a dynamic map.
Code: Select all
Structure dynMapString
Map a$()
EndStructure
; create
Define *db0.dynMapString
*db0 = AllocateMemory(SizeOf(dynMapString) )
InitializeStructure(*db0, dynMapString)
; modify
With *db0
; Between double quote is an absolutely personal syntax
; whom the coder has the whole freedom to imagine.
\a$("building(1)Level(3)Room(7)Wallface(North)Color") = "Gray"
EndWith
; destroy
ClearStructure(*db0, dynMapString)
FreeMemory(*db0)
Re: Example Application Code
There is ...
AllocateStructure and FreeStructure. See Help.
AllocateStructure and FreeStructure. See Help.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Example Application Code
I know, mk-soft, this very interesting tip, I can even recall the links :
Allocatestructure()
FreeStructure()
But, if I prefer 2 source code lines instead of only 1, it is for several reasons. You will have the opportunity to see it, and I maybe will have the pleasure to see you to be available to replace, them, and the features I work with memory !
The equivalent you talk about is this one :
Allocatestructure()
FreeStructure()
But, if I prefer 2 source code lines instead of only 1, it is for several reasons. You will have the opportunity to see it, and I maybe will have the pleasure to see you to be available to replace, them, and the features I work with memory !
The equivalent you talk about is this one :
Code: Select all
; (Shorter version adviced by mk-soft)
Structure dynMapString
Map a$()
EndStructure
; create
Define *db0.dynMapString = AllocateStructure(dynMapString)
; modify
With *db0
; Between double quote is an absolutely personal syntax
; whom the coder has the whole freedom to imagine.
\a$("building(1)Level(3)Room(7)Wallface(North)Color") = "Gray"
EndWith
; destroy
FreeStructure(*db0)