New to PB - questions to clear confusion
-
- User
- Posts: 20
- Joined: Sun Feb 14, 2021 2:55 am
- Location: Max Meadows, Virginia, USA
- Contact:
New to PB - questions to clear confusion
Good evening.
I'm considering switching over to PB for my business related projects. I'm experienced in VB.net as well as PHP, Python, and, years ago, C. I've dabbled in several other tools and languages but get tired of the needless complexity (and bloat) that seems to be inherent in most development environments plus I'm not a fan of OOP although I can do it. I've spent some time playing around with PB today and developed some questions that I have not found good answers.
1. Is there a particular program flow recommended? Something like how in VB you - Form -> Events-> Code?
2. When using the GUI form designer, how do you name the reference to the form in the properties (object) window? I was able to change the reference by editing the form code but it seems like this could be done in the GUI designer.
3. I created an initial form with a button and a text gadget. When I test it, the button is not visible although the form is. Is this because there are no events generated for the form?
Honestly I find the structure and code on the back quite simple from a code standpoint but the Form Designer/GUI has me a bit confused. Thanks in advance.
I'm considering switching over to PB for my business related projects. I'm experienced in VB.net as well as PHP, Python, and, years ago, C. I've dabbled in several other tools and languages but get tired of the needless complexity (and bloat) that seems to be inherent in most development environments plus I'm not a fan of OOP although I can do it. I've spent some time playing around with PB today and developed some questions that I have not found good answers.
1. Is there a particular program flow recommended? Something like how in VB you - Form -> Events-> Code?
2. When using the GUI form designer, how do you name the reference to the form in the properties (object) window? I was able to change the reference by editing the form code but it seems like this could be done in the GUI designer.
3. I created an initial form with a button and a text gadget. When I test it, the button is not visible although the form is. Is this because there are no events generated for the form?
Honestly I find the structure and code on the back quite simple from a code standpoint but the Form Designer/GUI has me a bit confused. Thanks in advance.
-
- User
- Posts: 25
- Joined: Thu Feb 04, 2021 9:27 pm
- Location: Nowhere Special, Arizona, USA
Re: New to PB - questions to clear confusion
I'm very new here as well. I found this post extremely helpful.
viewtopic.php?f=22&t=64684
viewtopic.php?f=22&t=64684
Last edited by Desert Polar Bear on Wed Feb 17, 2021 4:01 am, edited 1 time in total.
"You should never judge a book by its cover."
"A picture is worth a thousand words."
Well, which...? Shuddup!
- Desert Polar Bear • Nowhere Special • Arizona, USA
"A picture is worth a thousand words."
Well, which...? Shuddup!
- Desert Polar Bear • Nowhere Special • Arizona, USA
Re: New to PB - questions to clear confusion
The FormDesigner of Purebasic can be used to create individual windows very well (even if it is not quite perfect). However, I would switch off the event management of the FormDesigner and change it to constants.
You can set this under Preferences -> Form
- Disable New gadgets use #PB_Any by default
- Deactivate Generate event procedure
Include the form files with IncludeFile and write the event procedures yourself.
If you want to create multiple windows, you have to be careful to assign unique constant names to the windows and gadgets.
As I am a lazy writer, I have written a tool that adapts the gadget of several windows to the constants by extending the constant of the window as a prefix and creating a common file. I was also able to automate the creation of the event procedures and the call.
To learn Purebasic and how the event management of Purebasic works, you should first learn it yourself.
But if you want to have them automated like in VB6, you can have a look at my tool EventDesigner. (see signature)
You can set this under Preferences -> Form
- Disable New gadgets use #PB_Any by default
- Deactivate Generate event procedure
Include the form files with IncludeFile and write the event procedures yourself.
If you want to create multiple windows, you have to be careful to assign unique constant names to the windows and gadgets.
As I am a lazy writer, I have written a tool that adapts the gadget of several windows to the constants by extending the constant of the window as a prefix and creating a common file. I was also able to automate the creation of the event procedures and the call.
To learn Purebasic and how the event management of Purebasic works, you should first learn it yourself.
But if you want to have them automated like in VB6, you can have a look at my tool EventDesigner. (see signature)
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: New to PB - questions to clear confusion
Hi JaxMusic,
welcome to the PureBasic Community.
Honestly I do not use the gui designer.
Because of my small tools I do the gui stuff inside the code editor.
The important thing is, that the event management is the same.
Some of my "rules" from my personal "coding guidelines"
Please bear in mind, that I do not want to start a discussion on pro and cons of guidlines
You will see that there are different "styles" on the forums codes, and that is absolutly okay with me.
My solid rule:
-> EnableExplicit ;' always the first addition even to code from the forum (but you dont have to, its up to you)
Some Syntax (usage is up to you)
I use special prefix letters for
-> E for named enums i.e. Enumeration EWindow
-> T for structures i.e. Structure TProgramData
Here is a running example with different event management behavior (please see the comments)
I skipped the multi window event management for this time (maybe you can find this on existing solutions on the forum)
happy coding and stay healthy
welcome to the PureBasic Community.
Honestly I do not use the gui designer.
Because of my small tools I do the gui stuff inside the code editor.
The important thing is, that the event management is the same.
Some of my "rules" from my personal "coding guidelines"
Please bear in mind, that I do not want to start a discussion on pro and cons of guidlines
You will see that there are different "styles" on the forums codes, and that is absolutly okay with me.
My solid rule:
-> EnableExplicit ;' always the first addition even to code from the forum (but you dont have to, its up to you)
Some Syntax (usage is up to you)
I use special prefix letters for
-> E for named enums i.e. Enumeration EWindow
-> T for structures i.e. Structure TProgramData
Here is a running example with different event management behavior (please see the comments)
I skipped the multi window event management for this time (maybe you can find this on existing solutions on the forum)
Code: Select all
;' File : Sample.pb
EnableExplicit
DebugLevel 9 ;' all debug message on :-) -- also my style
#ProgramName$ = "Sample"
#ProgramMajorVersion$ = "1"
Enumeration EWindow ;' use of named enums is helpful, if you use several files
#WINDOW_Main
#WINDOW_SearchAndReplace
EndEnumeration
Enumeration EGadget ;'small projects with only one window (or max three)
#GADGET_CloseBtn
#GADGET_HelpBtn
#GADGET_Filename
#GADGET_New ;' nameing is not really useful
#GADGET_Open
#GADGET_Clear
EndEnumeration
;' this is possible -- thanks to the named enum you get always different IDs
Enumeration EGadget ;'midsize or bigger projects with more windows and many gadgets
#GADGET_Main_CloseBtn ;' use the Window name inside
#GADGET_Main_HelpBtn
; ...
#GADGET_SearchAndReplace_HelpBtn ;' second window
EndEnumeration
Enumeration EMenu
#MENU_New ;' sample
#MENU_Open
#MENU_Clear
EndEnumeration
;' Constants
#MainCaption$ = #ProgramName$ + " "+#ProgramMajorVersion$ + "." + #PB_Editor_BuildCount + " (" + #PB_Editor_CompileCount + ")"
#WindowFlags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget
;'
;' Example of BindEvent()
;'
Procedure OnEvent_SizeMainWindow()
Protected WndW, WndH :Debug #PB_Compiler_Procedure + "() ", 9
; Resize the gadget to fit the new window dimensions
;
WndW = WindowWidth(#WINDOW_Main)
WndH = WindowHeight(#WINDOW_Main)
ResizeGadget(#GADGET_CloseBtn, #PB_Ignore, #PB_Ignore, WndW - 16, #PB_Ignore)
ResizeGadget(#GADGET_Filename, #PB_Ignore, #PB_Ignore, WndW - 16, #PB_Ignore)
EndProcedure
;'
;' Example of SetWindowCallback()
;'
Procedure MainWindowCallback(hWnd, Message, wParam, lParam)
Protected result
result = #PB_ProcessPureBasicEvents
Select Message
Case #WM_SIZE
Select WParam
Case #SIZE_MINIMIZED :Debug "Window was minimized", 9
Case #SIZE_RESTORED :Debug "Window was restored", 9
Case #SIZE_MAXIMIZED :Debug "Window was maximized", 9
EndSelect
Case #WM_QUERYENDSESSION :Debug "WM_QUERYENDSESSION ", 9
result = #True
Case #WM_ENDSESSION :Debug "WM_ENDSESSION ", 9
If wParam = 1
;' now we have a series problem :-)
EndIf
EndSelect
ProcedureReturn result
EndProcedure
;'
;' example for main loop based event management
;'
Procedure OnEvent_NewFile()
EndProcedure
Procedure OnEvent_OpenFile()
EndProcedure
;---------------------------------------------------------------------------------------------------------------------
Procedure OpenMainWindow(WndW, WndH)
Protected hwnd
hwnd = OpenWindow(#WINDOW_Main, 0, 0, WndW, WndH, #MainCaption$, #WindowFlags)
If hwnd <> 0
StickyWindow(#WINDOW_Main, 1)
ButtonGadget(#GADGET_CloseBtn, 8, 8, WndW - 16, 25, "Close", #PB_Button_Default)
StringGadget(#GADGET_Filename, 8, 48, WndW - 16, 20, "c:\temp\dummy.txt")
;' add the gadgets, menus, etc. here
SetWindowCallback(@MainWindowCallback(), #WINDOW_Main)
BindEvent(#PB_Event_SizeWindow, @OnEvent_SizeMainWindow(), #WINDOW_Main)
EndIf
ProcedureReturn hwnd
EndProcedure
Procedure MainProgram()
Protected state
If OpenMainWindow(640, 480)
;' main loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow() ;' which window fired the event
Case #WINDOW_Main
Break ;' escape the main loop
Case #WINDOW_SearchAndReplace
;' do what ever you want to do
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #GADGET_New
OnEvent_NewFile()
Case #GADGET_Open
OnEvent_OpenFile()
; ...
Case #GADGET_Clear
; ...
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #MENU_New
OnEvent_NewFile()
Case #MENU_Open
OnEvent_OpenFile()
EndSelect
EndSelect
ForEver
EndIf
EndProcedure
End MainProgram()
happy coding and stay healthy
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Re: New to PB - questions to clear confusion
Hi JaxMusic,
welcome to the PureBasic community. You can find many resource links on my personal website. There is a series of tutorials for beginners too. Personally i use PureVision as GUI designer and am happy with that combination for the last decades
That's all i personally need, but lately sql tools are an optional help too. PureBasic/PureVision is an excellent investment to comfortably do desktop or server applications for windows/linux/Mac OS.
Check my website at http://www.bitblazer.de for a complete? collection of purebasic links with thousands of samples, tips and tricks. Click Links -> PureBasic -> Resources
welcome to the PureBasic community. You can find many resource links on my personal website. There is a series of tutorials for beginners too. Personally i use PureVision as GUI designer and am happy with that combination for the last decades
That's all i personally need, but lately sql tools are an optional help too. PureBasic/PureVision is an excellent investment to comfortably do desktop or server applications for windows/linux/Mac OS.
Check my website at http://www.bitblazer.de for a complete? collection of purebasic links with thousands of samples, tips and tricks. Click Links -> PureBasic -> Resources
-
- User
- Posts: 20
- Joined: Sun Feb 14, 2021 2:55 am
- Location: Max Meadows, Virginia, USA
- Contact:
Re: New to PB - questions to clear confusion
Thanks for the responses given so far. Some of the answers do address, in a way, the questions I have. But would still like clarity. Thanks.
1. Is there a particular program flow recommended? Something like how in VB you - Form -> Events-> Code?
2. When using the GUI form designer, how do you name the reference to the form in the properties (object) window? I was able to change the reference by editing the form code but it seems like this could be done in the GUI designer.
3. I created an initial form with a button and a text gadget. When I test it, the button is not visible although the form is. Is this because there are no events generated for the form?
1. Is there a particular program flow recommended? Something like how in VB you - Form -> Events-> Code?
2. When using the GUI form designer, how do you name the reference to the form in the properties (object) window? I was able to change the reference by editing the form code but it seems like this could be done in the GUI designer.
3. I created an initial form with a button and a text gadget. When I test it, the button is not visible although the form is. Is this because there are no events generated for the form?
- Fangbeast
- PureBasic Protozoa
- Posts: 4747
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: New to PB - questions to clear confusion
That's the way I do it, with all the visual designers I have ever tried.Form -> Events-> Code?
Once the form is designed, you should never manually edit it unless you have some strange third-party controls you need to replace a built-in one with but even that is done without touching the form code.
Design the form, give all objects long winded names that will tell you what they are when you are coding for them, let the visual designer (Not sure if the pb one does this) create a basic loop for you such as the one below. Designers like the one I use from Reelmedia create that and the basic set of controls (Gadgets, PB parlance) and then you add your events that you want to check for and then design the code (Procedures) you want them to triggerr.
Code: Select all
Repeat
EventID = WaitWindowEvent()
MenuID = EventMenu()
GadgetID = EventGadget()
WindowID = EventWindow()
TimerID = EventTimer()
Select EventID
Case #PB_Event_CloseWindow
Select WindowID
Case #Window_Mywindow
CloseWindow(#Window_Mywindow)
EndSelect
EndSelect
Until #PB_Event_CloseWindow = #True
End
Amateur Radio, D-STAR/VK3HAF
Re: New to PB - questions to clear confusion
Here's a quick six-step example to illustrate the structure, functionality, and implementation of form files.JaxMusic wrote:...But would still like clarity.
1. Open a new form (press F11).
2. Position and size an IMAGE gadget and a BUTTON gadget onto it (ensure their positions don't overlap).
3. In the CAPTION property of the button gadget, type "LOAD IMAGE" (without quotes).
4. In the EVENT PROCEDURE field of the button gadget, type "buttonEvent" (without quotes).
5. Save this form as myForm.pbf (take note of the saved location paths).
The code generated by the Form Designer should look something like this (with the GENERATE EVENTS PROCEDURE option in the Window_0 layout properties selected):
Code: Select all
;
; This code is automatically generated by the FormDesigner.
; Manual modification is possible to adjust existing commands, but anything else will be dropped when the code is compiled.
; Event procedures needs to be put in another source file.
;
Global Window_0
Global Image_0, Button_0
Declare buttonEvent(EventType)
Procedure OpenWindow_0(x = 0, y = 0, width = 480, height = 320)
Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu)
Image_0 = ImageGadget(#PB_Any, 16, 16, 448, 240, 0)
Button_0 = ButtonGadget(#PB_Any, 16, 272, 448, 32, "LOAD IMAGE")
EndProcedure
Procedure Window_0_Events(event)
Select event
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case Button_0
buttonEvent(EventType())
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
Code: Select all
; ensure that the form file (myForm.pbf) is in the same folder as this code file
; otherwise ensure that the proper path to the form file is included - eg: C:\path\folder\myForm.pbf
XIncludeFile "myForm.pbf"
; include these image plug-ins to enable JPG and PNG image support (BMP support is built in)
UseJPEGImageDecoder()
UsePNGImageDecoder()
; create a procedure for the button event and name it according to the name given in myForm.pb (buttonEvent)
; this procedure takes the event type as a parameter and is called when the button in myForm.pb (Button_0) is clicked
Procedure buttonEvent(event_type)
; some code to select and load an image into the image gadget
; open a file explorer dialog for selecting an image file
pattern.s = "Images (BMP, JPG, PNG)|*.bmp;*.jpg;*.png"
imageFile.s = OpenFileRequester("Select an image file", "", pattern, 0)
imageType.s = LCase(GetExtensionPart(imageFile))
imageSize = FileSize(imageFile)
; some cursory validation on the selected image file before attempting to load it
If imageSize > 0 And (imageType = "bmp" Or imageType = "jpg" Or imageType = "png")
image_id = LoadImage(#PB_Any, imageFile)
; size the image to fit the image gadget
ResizeImage(image_id, 448, 240)
; set the selected image into the image gadget in myForm.pb (Image_0)
SetGadgetState(Image_0, ImageID(image_id))
EndIf
EndProcedure
; this function was generated by the form designer
; call this function to display the form in myForm.pbf
OpenWindow_0()
; the main event loop
Repeat
event = WaitWindowEvent()
; this function was generated by the form designer
; call this function and pass it the EVENT value to process the events required by myForm.pbf
; STATUS holds the boolean result from this function - FALSE only when the window is closed
status = Window_0_Events(event)
; break the event loop and end the program when STATUS = FALSE
Until status = #False
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: New to PB - questions to clear confusion
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: New to PB - questions to clear confusion
Hi,
maybe my answers help you a little
The link between forms and code are the constants #WINDOWS_* or #GADGET_* or the WIN_ID, GDT_ID variables if #PB_Any is used in the create procedures (OpenWindow, TextGadget, ButtonGadget, and so on). A general recommendation is to separate the Forms and the Code into several files and use XIncludeFile "<filename>".
Hint: Use the Menu 'Form | Switch Code/Design View' to see the result. All this is going through the compiler. It is not like C with a separate resource file.
If I would use the VD and I define my main window like
Properties - Variable: Window_0 ;' <-- default, name it to your liking
it leads to a code like this:
If you have only created the form, then you are still missing the start and the (as i call it) mainloop.
This additional code should not be stored in the form file, the form should be included via xincludefile instead.
see help for WaitWindowEvent() and the article about window management
Minimum additional code to the above VD created Form and Event you need is this:
IMHO this is not the best implementation because of lack on error handling and so on, but that is a different story.
maybe my answers help you a little
IMHO there is not only one way. As you can see, there are many different possibilities. In the end, you have to choose your way.1. Is there a particular program flow recommended? Something like how in VB you - Form -> Events-> Code?
The link between forms and code are the constants #WINDOWS_* or #GADGET_* or the WIN_ID, GDT_ID variables if #PB_Any is used in the create procedures (OpenWindow, TextGadget, ButtonGadget, and so on). A general recommendation is to separate the Forms and the Code into several files and use XIncludeFile "<filename>".
2. When using the GUI form designer, how do you name the reference to the form in the properties (object) window? I was able to change the reference by editing the form code but it seems like this could be done in the GUI designer.
Hint: Use the Menu 'Form | Switch Code/Design View' to see the result. All this is going through the compiler. It is not like C with a separate resource file.
If I would use the VD and I define my main window like
Properties - Variable: Window_0 ;' <-- default, name it to your liking
it leads to a code like this:
Code: Select all
Enumeration FormWindow ; <-- named enums :-)
#Window_0
EndEnumeration
Enumeration FormGadget
#Button_0
#Text_0
EndEnumeration
Procedure OpenWindow_0(x = 0, y = 0, width = 600, height = 400)
OpenWindow(#Window_0, x, y, width, height, "", #PB_Window_SystemMenu)
ButtonGadget(#Button_0, 128, 48, 104, 32, "")
TextGadget(#Text_0, 16, 56, 100, 25, "")
EndProcedure
Procedure Window_0_Events(event)
Select event
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu() ; <-- here you have to work on menu events
EndSelect
Case #PB_Event_Gadget
Select EventGadget() ; <-- here the events of the gadgets
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
3. I created an initial form with a button and a text gadget. When I test it, the button is not visible although the form is. Is this because there are no events generated for the form?
If you have only created the form, then you are still missing the start and the (as i call it) mainloop.
This additional code should not be stored in the form file, the form should be included via xincludefile instead.
see help for WaitWindowEvent() and the article about window management
Minimum additional code to the above VD created Form and Event you need is this:
Code: Select all
Define Event
;' call this first to create the window
OpenWindow_0() ; <- can be empty because of (x = 0, y = 0, width = 600, height = 400)
;' main loop
Repeat
Event = WaitWindowEvent()
If Window_0_Events(Event) = 0
Break
EndIf
ForEver
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Re: New to PB - questions to clear confusion
I like my method with constants and virtual tables on the event procedures. Then connect with BindEvent and that's it. See EventDesigner.
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: New to PB - questions to clear confusion
I learned the old school way from Petzold (in C), so I still do it that way. It's all manual, but when I started pb I didn't want to add a new process to the new language learning curve.
I might for the next project... But I keep saying that.Form -> Events-> Code?
-
- User
- Posts: 20
- Joined: Sun Feb 14, 2021 2:55 am
- Location: Max Meadows, Virginia, USA
- Contact:
Re: New to PB - questions to clear confusion
Thanks for the information. I was able to get the code working. It did have a bug in it but I don't know if it was system generated. This code in the form:
Declare buttonEvent(EventType)
versus the procedure
Procedure buttonEvent(event_type)
I changed the procedure reference to match. I am guessing that EventType is a system variable, so the procedure would have to match it?
Questions:
How does the compiler know where to start? There is no void main() like in C. Does it just start at code that it first encounters that is not in a procedure?
Thanks. Jack/Jax
Declare buttonEvent(EventType)
versus the procedure
Procedure buttonEvent(event_type)
I changed the procedure reference to match. I am guessing that EventType is a system variable, so the procedure would have to match it?
Questions:
How does the compiler know where to start? There is no void main() like in C. Does it just start at code that it first encounters that is not in a procedure?
What do you mean by take note of the paths? Is there an organizational issue here that I should be cognizant of? In this case I just put all the files in the same test directory I'm using.TI-994A wrote: Save this form as myForm.pbf (take note of the saved location paths).
I assume this is because the form is exclusive to form procedures?TI-994A wrote: ; Event procedures needs to be put in another source file.
Are these "#PB_Event" constants always generated in a form?TI-994A wrote:
Case #PB_Event_CloseWindow
ProcedureReturn #False
Thanks. Jack/Jax
Re: New to PB - questions to clear confusion
This book will likely answer your questions.
viewtopic.php?f=14&t=37059&p=563379&hil ... ad#p563379
All of the gadget events have constants assigned, and described in the pb manual. (Not referring to the aforementioned book.)
The code starts at the first statement, although procedures are "jumped over" meaning they are actually placed last in asm, iirc. Therefore, you don't need a "main" like C, although many of us start with a main-like proc so the only code not encapsulated in a proc is a call to that proc. For short & simple code, I might skip that main and put the loop out in free code space.
As for paths, you can use form files as includes or as a project, and either way, you want to know which directory they are in.
viewtopic.php?f=14&t=37059&p=563379&hil ... ad#p563379
All of the gadget events have constants assigned, and described in the pb manual. (Not referring to the aforementioned book.)
The code starts at the first statement, although procedures are "jumped over" meaning they are actually placed last in asm, iirc. Therefore, you don't need a "main" like C, although many of us start with a main-like proc so the only code not encapsulated in a proc is a call to that proc. For short & simple code, I might skip that main and put the loop out in free code space.
As for paths, you can use form files as includes or as a project, and either way, you want to know which directory they are in.