If the goal is to create multiple forms without worrying about object clashing, perhaps
modules might be a good choice. Coupled with PureBasic's dynamic object numbering
(#PB_Any), multiple forms can be created with a
fire-and-forget approach, even if they contain duplicate object names.
Here's an example where both forms are called
PanelApp with corresponding
OpenPanelApp() procedures, and both forms contain buttons named
Button_0.
win1Form.pbf
Code: Select all
;
; This code is automatically generated by the Form Designer.
; Manual modification is possible to adjust existing commands, but anything else will be dropped when the code is compiled.
; Event procedures need to be put in another source file.
;
Global PanelApp
Global Tree_0, Panel_0, Button_0
Enumeration FormMenu
#MenuItem_1
#MenuItem_2
#MenuItem_3
#MenuItem_4
#MenuItem_5
EndEnumeration
Procedure OpenPanelApp(x = 0, y = 0, width = 1170, height = 650)
PanelApp = OpenWindow(#PB_Any, x, y, width, height, "Boekhouding", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateMenu(0, WindowID(PanelApp))
MenuTitle("Bestand")
MenuItem(#MenuItem_1, "Open Window 2")
MenuItem(#MenuItem_2, "MenuItem 1")
MenuItem(#MenuItem_3, "MenuItem 2")
MenuTitle("Bewerken")
MenuItem(#MenuItem_4, "MenuItem 3")
MenuTitle("MenuTitle")
MenuItem(#MenuItem_5, "MenuItem 4")
Tree_0 = TreeGadget(#PB_Any, 0, 0, 190, 666)
Panel_0 = PanelGadget(#PB_Any, 190, 0, 1130, 666)
AddGadgetItem(Panel_0, -1, "Klanten")
AddGadgetItem(Panel_0, -1, "Offertes")
Button_0 = ButtonGadget(#PB_Any, 10, 120, 380, 30, "Window 2 Panel Button")
CloseGadgetList()
EndProcedure
win2Form.pbf
Code: Select all
;
; This code is automatically generated by the Form Designer.
; Manual modification is possible to adjust existing commands, but anything else will be dropped when the code is compiled.
; Event procedures need to be put in another source file.
;
Global PanelApp
Global Button_0
Enumeration FormMenu
#MenuItem_1
EndEnumeration
Procedure OpenPanelApp(x = 0, y = 0, width = 400, height = 200)
PanelApp = OpenWindow(#PB_Any, x, y, width, height, "Boekhouding Child", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateMenu(0, WindowID(PanelApp))
MenuTitle("MenuTitle")
MenuItem(#MenuItem_1, "MenuItem 1")
Button_0 = ButtonGadget(#PB_Any, 10, 120, 380, 30, "Window 2 Button")
EndProcedure
win1Module.pb
Code: Select all
DeclareModule win1
Declare OpenPanelApp(x = 0, y = 0, width = 1170, height = 650)
Declare initWin()
Global PanelApp
#OpenWin2 = #PB_Event_FirstCustomValue
EndDeclareModule
Module win1
XIncludeFile "win1Form.pbf"
Procedure win1Handler()
PostEvent(#PB_Event_CloseWindow)
EndProcedure
Procedure win1GadgetHandler()
Select EventGadget()
Case Tree_0
Debug "it's the tree from Window 1."
Case Panel_0
Debug "it's the panel from Window 1."
Case Button_0
Debug "it's the button from Window 1."
EndSelect
EndProcedure
Procedure win1MenuHandler()
If EventWindow() = PanelApp
Select EventMenu()
Case #MenuItem_1
PostEvent(#OpenWin2)
Case #MenuItem_2
Debug "it's menu 1 from Window 1."
Case #MenuItem_3
Debug "it's menu 2 from Window 1."
Case #MenuItem_4
Debug "it's menu 3 from Window 1."
Case #MenuItem_5
Debug "it's menu 4 from Window 1."
EndSelect
EndIf
EndProcedure
Procedure initWin()
AddGadgetItem (Tree_0, -1, "Tree_0 Item")
BindEvent(#PB_Event_Menu, @win1MenuHandler(), PanelApp)
BindEvent(#PB_Event_Gadget, @win1GadgetHandler(), PanelApp)
BindEvent(#PB_Event_CloseWindow, @win1Handler(), PanelApp)
EndProcedure
EndModule
win2Module.pb
Code: Select all
DeclareModule win2
Declare OpenPanelApp(x = 0, y = 0, width = 400, height = 200)
Declare initWin()
Global PanelApp
EndDeclareModule
Module win2
XIncludeFile "win2Form.pbf"
Procedure win2Handler()
PostEvent(#PB_Event_CloseWindow)
EndProcedure
Procedure win2GadgetHandler()
Select EventGadget()
Case Button_0
Debug "it's the button from Window 2."
EndSelect
EndProcedure
Procedure win2MenuHandler()
If EventWindow() = PanelApp
Select EventMenu()
Case #MenuItem_1
Debug "it's menu 1 from Window 2."
EndSelect
EndIf
EndProcedure
Procedure initWin()
BindEvent(#PB_Event_Menu, @win2MenuHandler(), PanelApp)
BindEvent(#PB_Event_Gadget, @win2GadgetHandler(), PanelApp)
BindEvent(#PB_Event_CloseWindow, @win2Handler(), PanelApp)
EndProcedure
EndModule
mainApp.pb
Code: Select all
XIncludeFile "win1Module.pb"
XIncludeFile "win2Module.pb"
win1::OpenPanelApp()
win1::initWin()
Repeat
event = WaitWindowEvent()
Select event
Case win1::#OpenWin2
win2::OpenPanelApp()
win2::initWin()
Case #PB_Event_CloseWindow
Select EventWindow()
Case win1::PanelApp
appQuit = #True
Case win2::PanelApp
CloseWindow(win2::PanelApp)
EndSelect
EndSelect
Until appQuit
The two forms work seamlessly together and their dynamically-assigned object names do not clash, despite being exactly the same.
However, the clear caveat, even with modules, is the menu. The menu from
win1 was lost after opening/closing
win2. In the PureBasic form designer, there is currently no way of creating menus with dynamic numbering, relegating them to always being created with the object number zero. Each subsequently opened form with menus would invariably overwrite the menu of the active form.
While the object numbers of the menus could be manually amended, the form designer would simply revert such changes whenever it is edited.
To circumvent this, here is a short routine that could automate the process each time the forms have been edited. Simply include the form names in the array here, and run it before debugging the project, or even before final compilation. Whenever the form files are edited again, save and close them, and run this again. It simply changes the menu object numbers for each form incrementally, and would not corrupt the original form files themselves.
Code: Select all
Dim forms.s(1) ; increase as required
forms(0) = "win1Form.pbf"
forms(1) = "win2Form.pbf"
For i = 0 To 1
form$ = ""
ReadFile(0, forms(i))
While Not Eof(0)
line$ = ReadString(0)
If FindString(line$, "CreateMenu(0")
line$ = ReplaceString(line$, "CreateMenu(0", "CreateMenu(" + i)
EndIf
form$ + line$ + #CRLF$
Wend
CloseFile(0)
OpenFile(0, forms(i))
WriteString(0, form$)
CloseFile(0)
Next i
After running the above code, run
mainApp.pb again, and the menus for
win1 would remain intact after opening/closing
win2.
Reopening the form files for further editing would undo these changes, with no harm done.
With modules, and this small workaround, working with PureBasic's form designer becomes a breeze again.
