Example Application Code

Just starting out? Need help? Post your questions and find answers here.
lesserpanda
User
User
Posts: 65
Joined: Tue Feb 11, 2020 7:50 am

Example Application Code

Post by lesserpanda »

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.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Example Application Code

Post by Olli »

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
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.
Hello lady,

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 !
lesserpanda
User
User
Posts: 65
Joined: Tue Feb 11, 2020 7:50 am

Re: Example Application Code

Post by lesserpanda »

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

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
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Example Application Code

Post by Olli »

lesserpanda wrote: Wed Nov 23, 2022 5:39 amSorry for basic question
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.
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: Example Application Code

Post by jacdelad »

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
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: Example Application Code

Post by Axolotl »

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.

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
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Example Application Code

Post by Olli »

I m agree with Axolotl for this code part :

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 
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

; generic using example : use of "#PB_Any" 
myVariable = ButtonGadget(#PB_Any, x, y, w, h, text)
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: Example Application Code

Post by Axolotl »

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.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
KosterNET
User
User
Posts: 30
Joined: Tue Mar 22, 2016 10:08 pm

Re: Example Application Code

Post by KosterNET »

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:

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
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:

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)
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
lesserpanda
User
User
Posts: 65
Joined: Tue Feb 11, 2020 7:50 am

Re: Example Application Code

Post by lesserpanda »

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.
User avatar
Bisonte
Addict
Addict
Posts: 1226
Joined: Tue Oct 09, 2007 2:15 am

Re: Example Application Code

Post by Bisonte »

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.
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.
only one opendatabase call and one closedatabase call will not work ;)
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
lesserpanda
User
User
Posts: 65
Joined: Tue Feb 11, 2020 7:50 am

Re: Example Application Code

Post by lesserpanda »

Thank you for your insight. This has helped me alot in avoiding issues with DB.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Example Application Code

Post by Olli »

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... :

Code: Select all

GeneralMediumLocal
... 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.

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)
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Example Application Code

Post by mk-soft »

There is ...

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
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Example Application Code

Post by Olli »

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 :

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)
Post Reply