Page 1 of 2
Minimising the role of .PBF form files
Posted: Sat Aug 27, 2022 9:35 pm
by Oso
I’ve been using PureBasic for a short time. The idea behind the .PBF file has remained a bit unclear to me, although I understand how it works. Is there a good argument for storing the absolute minimum gadget specifiers in the .PBF file and nothing else besides those?
I’ve struggled a bit to understand why the .PBF concept should contain any code logic. I feel that its use is primarily a means of allowing the form designer to re-create the code for the gadgets, without overwriting the programmer’s logic.
If this assumption is correct, and .PBF is only there to specify parameters of gadgets, isn’t there a good case for storing only those gadgets and nothing else? I used the very helpful post by @TI-994A to understand the concept - at
viewtopic.php?f=22&t=64684. It seems from looking at this link, that there has been a conceptual change in the past, because he refers to the following…
File menu – Preferences - In the left panel of the dialog that appears, select Form, then in the dialog window, make sure that the Generate Event procedure and Generate Event Loop options are selected.
The latter option is of course now absent from PB, but it seems that even the Generate Event option would be better if this code is placed in the .PB instead.
Is there anything wrong with the suggested minimalist concept below, other than the fact that when we make a forms-design change, PB will recreate the global variables? I moved the global declaration to the top of the .PB, above the XIncludeFile. This incidentally is TI-994A’s example restructured. It would be interesting to gain other developers' better insights here, before I embark on something. Thanks.
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
Procedure OpenWindow_0(x = 0, y = 0, width = 300, height = 400)
Window_0 = OpenWindow(#PB_Any, x, y, width, height, "My Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Button_0 = ButtonGadget(#PB_Any, 160, 70, 100, 25, "Click Me")
Text_0 = TextGadget(#PB_Any, 30, 20, 100, 25, "This is a label")
String_0 = StringGadget(#PB_Any, 30, 70, 100, 25, "")
EndProcedure
Code: Select all
Global Window_0
Global Button_0, Text_0, String_0
XIncludeFile "MyForm.pbf"
Procedure buttonEvent(eventType.i)
text$ = GetGadgetText(String_0) ;get the text from the text box (identifier = String_0)
SetGadgetText(Text_0, text$) ;and place it in the label (identifier = Text_0)
EndProcedure
Procedure Window_0_Events(event)
Select event
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Gadget
Select EventGadget()
Case Button_0
buttonEvent(EventType())
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
OpenWindow_0()
Repeat
event = WaitWindowEvent()
Until Window_0_Events(event) = #False
Re: Minimising the role of .PBF form files
Posted: Sat Aug 27, 2022 11:24 pm
by Mijikai
I see no error checking anywhere which is bad imho.
Re: Minimising the role of .PBF form files
Posted: Sun Aug 28, 2022 2:03 am
by mk-soft
I use the FormDesigner without the automatically created event procedure. I prefer to write these myself. I also don't use #PB_Any, but the method with the constants.
After creating the window from the FormDesigner, I use IsWindow to check whether the window is open.
Since I don't like the event management of the FormDesigner and am lazy about writing, I use my EventDesigner to automatically create all the necessary procedures from one or more windows (FormXYZ.pbf) to create an executable programme.
Re: Minimising the role of .PBF form files
Posted: Sun Aug 28, 2022 2:40 am
by BarryG
I don't use the form designer because it overwrites your code. It should just be a standalone ".PBI" file that you include in your main source, that creates the windows and gadgets only. Nothing else.
Re: Minimising the role of .PBF form files
Posted: Sun Aug 28, 2022 7:44 pm
by Oso
mk-soft wrote: Sun Aug 28, 2022 2:03 am
I use the FormDesigner without the automatically created event procedure. I prefer to write these myself. I also don't use #PB_Any, but the method with the constants.
Thanks for the reply. Where you say you don't use #PB_Any, do you specify your own number for each gadget, without an assignment variable and then refer to each in the code by its relative number (in this case below 0 - 3)? The post I worked from at
viewtopic.php?f=22&t=64684 was inconsistent between the examples...
Code: Select all
OpenWindow(0, 0, 0, 300, 200, "My Window", wFlags)
TextGadget(1, 50, 30, 200, 30, "This is a label...")
StringGadget(2, 50, 70, 200, 30, "")
ButtonGadget(3, 50, 120, 200, 30, "Click Me")
Re: Minimising the role of .PBF form files
Posted: Sun Aug 28, 2022 7:51 pm
by Oso
BarryG wrote: Sun Aug 28, 2022 2:40 am
I don't use the form designer because it overwrites your code. It should just be a standalone ".PBI" file that you include in your main source, that creates the windows and gadgets only. Nothing else.
Thanks @BarryG - Out of interest, do you use some other means of designing forms? I find the forms designer to help with aesthetic balance, which is difficult to achieve with long-hand coding of the objects and manually calculating the positioning. I realise of course there are other design tools, but for now I've been sticking with what's provided in PB.
Re: Minimising the role of .PBF form files
Posted: Mon Aug 29, 2022 12:40 am
by mk-soft
Read PB-Help 'Various Topics' -> 'PureBasic objects'
Re: Minimising the role of .PBF form files
Posted: Mon Aug 29, 2022 5:27 pm
by Oso
mk-soft wrote: Mon Aug 29, 2022 12:40 am
Read PB-Help 'Various Topics' -> 'PureBasic objects'
Thanks for the topic on this. I'm curious about the underlined comment below...
I. Indexed numbering - The first available index number is 0 and subsequent indexes are allocated sequentially. This means that if you use the number 0 and then the number 1000, 1001 indexes will be allocated and 999 (from 1 to 999) will be unused, which is not an efficient way to use indexed objects.
I wonder how dynamic numbering avoids the above mentioned inefficiency of indexed numbering, because dynamic numbering appears to just simply allocate a high value to the object number, with wide gaps in the numbering. For example this code gives the below results...
Code: Select all
test1 = CreateImage(#PB_Any, 640, 480)
test2 = CreateImage(#PB_Any , 800, 800)
Debug test1
Debug test2
32575056
32575136
Wouldn't this be the case that 0 - 32575055 and 32575057 - 32575135 have similarly been allocated too, or is the underlying principle different?
Re: Minimising the role of .PBF form files
Posted: Mon Aug 29, 2022 6:28 pm
by mk-soft
Objects with #PB_Any its not an Array, its dynamic memory management
Re: Minimising the role of .PBF form files
Posted: Mon Aug 29, 2022 8:36 pm
by Oso
mk-soft wrote: Mon Aug 29, 2022 6:28 pm
Objects with #PB_Any its not an Array, its dynamic memory management
Got it. I just tried two fixed index numbers with a large gap between them. Yes, I can see the effect that has on the memory consumed by the running executable.
Re: Minimising the role of .PBF form files
Posted: Mon Aug 29, 2022 10:58 pm
by BarryG
Oso wrote: Sun Aug 28, 2022 7:51 pmThanks @BarryG - Out of interest, do you use some other means of designing forms?
I do it by hand, in multiples of 10 pixels. So my top-left gadget would be at position 10,10. If that gadget is 50 pixels wide (say a button), then the gadget to the right of it would be at X position 70 (I mentally add 10+50+10). The math isn't hard when doing it like that. I like the fine control I get over every gadget this way.
Re: Minimising the role of .PBF form files
Posted: Tue Aug 30, 2022 8:40 pm
by Oso
BarryG wrote: Mon Aug 29, 2022 10:58 pm
I do it by hand, in multiples of 10 pixels. So my top-left gadget would be at position 10,10. If that gadget is 50 pixels wide (say a button), then the gadget to the right of it would be at X position 70 (I mentally add 10+50+10). The math isn't hard when doing it like that. I like the fine control I get over every gadget this way.
Thanks @BarryG it's a help to know how other PB folks do things. I've been a character-based software developer for most of my life

which of course means 80 x 25 rows. I don't always admit to this of course.
I suppose there's always the option with PB of using the forms designer once and then copying the objects that it has created, into your code and leaving it at that. In other words, don't bother to use the forms designer for further changes, but use it just for the initial layout.
I must admit I like the designer in PB - it works great, but I'm not quite so keen on the relationship between the .PBF and the .PB. It just feels a bit like a workaround, although it's still a good tool even so.
Re: Minimising the role of .PBF form files
Posted: Wed Aug 31, 2022 11:26 am
by Axolotl
Oso wrote: Sun Aug 28, 2022 7:44 pm
... The post I worked from at
viewtopic.php?f=22&t=64684 was inconsistent between the examples...
Code: Select all
OpenWindow(0, 0, 0, 300, 200, "My Window", wFlags)
TextGadget(1, 50, 30, 200, 30, "This is a label...")
StringGadget(2, 50, 70, 200, 30, "")
ButtonGadget(3, 50, 120, 200, 30, "Click Me")
yupp, that's why i always recommend to use my personal coding guidelines...
Simply written: Never use numbers, always use predefined constants or like here enumerations.
Disadvantage: You have to write more code. In larger applications, however, this will be worthwhile. Especially because there are not so many errors caused by wrong numbers.
Adapted to the above example.
Code: Select all
EnableExplicit ; <-- never forget this !!!
; Use named enumerations
; + can be continued in any sourcefile
; + starts by 1 so 0 can be used as undefined values
Enumeration EWindow 1
#WINDOW_Main
EndEnumeration
; ; ... this can be used in any other source file
;
; CompilerIf Not Defined(EWindow, #PB_Enumeration)
; Enumeration EWindow 1 ; <-- first time : set start number
; CompilerElse
; Enumeration EWindow ; <-- next time : it will continue the iteration
; CompilerEndIf
; #WINDOW_Trace
; EndEnumeration
;
Enumeration EGadget 1
#GADGET_LblLabel ; use better names in real applications
#GADGET_StrInput
#GADGET_BtnClickMe
EndEnumeration
Define wFlags = #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered
If OpenWindow(#WINDOW_Main, 0, 0, 300, 200, "My Window", wFlags) ; <> 0
TextGadget(#GADGET_LblLabel, 50, 30, 200, 30, "This is a label...")
StringGadget(#GADGET_StrInput, 50, 70, 200, 30, "")
ButtonGadget(#GADGET_BtnClickMe, 50, 120, 200, 30, "Click Me")
; some kind of main loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow ; deal with the events here or use BindEvent()
Break ; exit the main loop
Case #PB_Event_Gadget
Select EventGadget()
Case #GADGET_StrInput
Select EventType()
Case #PB_EventType_Change :Debug "Change" ; The text has been modified by the user.
Case #PB_EventType_Focus :Debug "Focus" ; The StringGadget got the focus.
Case #PB_EventType_LostFocus :Debug "LostFocus" ; The StringGadget lost the focus.
EndSelect ; <-- added, because this is the right place for it
Case #GADGET_BtnClickMe
Debug "Click on ClickMe Button"
;EndSelect ; <-- commented out, because wrong position here!
EndSelect
EndSelect
ForEver
EndIf
In fact, the form designer is a little-noticed appendage. Recently, as open source, it can also be changed/extended by anyone.
Edit : volatility error corrected. (see comments)
Re: Minimising the role of .PBF form files
Posted: Wed Aug 31, 2022 2:51 pm
by mk-soft
Already posted many times
Basis for a program
Code: Select all
;-TOP
#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"
Enumeration Windows
#Main
EndEnumeration
Enumeration MenuBar
#MainMenu
EndEnumeration
Enumeration MenuItems
#MainMenuAbout
#MainMenuExit
EndEnumeration
Enumeration Gadgets
#MainEdit
#MainButtonOk
#MainButtonCancel
EndEnumeration
Enumeration StatusBar
#MainStatusBar
EndEnumeration
Procedure UpdateWindow()
Protected dx, dy
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
; Resize gadgets
ResizeGadget(#MainEdit, 5, 5, dx - 10, dy - 45)
ResizeGadget(#MainButtonok, 10, dy - 35, 120, 30)
ResizeGadget(#MainButtonCancel, dx - 130, dy - 35, 120, 30)
EndProcedure
Procedure Main()
Protected dx, dy
#MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
; Menu
CreateMenu(#MainMenu, WindowID(#Main))
MenuTitle("&File")
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
MenuItem(#PB_Menu_About, "")
CompilerElse
MenuItem(#MainMenuAbout, "About")
MenuBar()
CompilerEndIf
MenuItem(#MainMenuExit, "E&xit")
; StatusBar
CreateStatusBar(#MainStatusBar, WindowID(#Main))
AddStatusBarField(#PB_Ignore)
; Gadgets
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
EditorGadget(#MainEdit, 5, 5, dx -10, dy - 45)
ButtonGadget(#MainButtonok, 10, dy - 35, 120, 30, "Ok")
ButtonGadget(#MainButtonCancel, dx - 130, dy - 35, 120, 30, "Cancel")
; Bind Events
BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
; Event Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
Break
EndSelect
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
CompilerEndIf
Case #MainMenuAbout
MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
Case #MainMenuExit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #MainEdit
Select EventType()
Case #PB_EventType_Change
;
EndSelect
Case #MainButtonOk
;
Case #MainButtonCancel
;
EndSelect
EndSelect
ForEver
EndIf
EndProcedure : Main()
Re: Minimising the role of .PBF form files
Posted: Wed Aug 31, 2022 3:45 pm
by Axolotl
yepp, you can't argue with that.
I only miss the extremely helpful 'EnableExplicit'.
But that is just my opinion.
Happy coding and stay healthy.