How to open and reopen a window from a first window?
Re: How to open and reopen a window from a first window?
It was taking it over. But the second time it is gone. Not workable. I 'solved' it by manualy coding the menu's in de procedures file. It's getting more clear bit by bit. I'm getting to a system that will be good to build larger applications that is manageable for maintaining. I'm using the template feature for new form procedures. In the template I use something like ;<NameForm> then I highlighted that with the issue tool. Everything starts with the name of the form. So I only need to change that. Find and replace. And a new procedures file is ready to be programmed.
Re: How to open and reopen a window from a first window?
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
win2Form.pbf
win1Module.pb
win2Module.pb
mainApp.pb
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.
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.
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.
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: How to open and reopen a window from a first window?
So modules act as events. Module::event()?
I will look if this would make life simpler. In the meantime I have about 8 windows running.
Templates make a difference. So does issues.
I found how to copy the prefs. Would be nice to see a way to backup or transfer them in the IDE.
I think in VB and VBA modules are standard and not showing how they connect. Just select the object and the event and code away. But not complaining. Purebasic has a lot more going for it. Just need to get into it.
I will look if this would make life simpler. In the meantime I have about 8 windows running.
Templates make a difference. So does issues.
I found how to copy the prefs. Would be nice to see a way to backup or transfer them in the IDE.
I think in VB and VBA modules are standard and not showing how they connect. Just select the object and the event and code away. But not complaining. Purebasic has a lot more going for it. Just need to get into it.
Re: How to open and reopen a window from a first window?
Not at all. Modules introduce the concept of namespaces to PureBasic. Their environments are virtual blackboxes, so duplicate names and labels would not clash between them.
In the example provided, the two forms are called by their corresponding handlers, which have been placed within independent modules. So the constant names, variable names, and procedure labels of the two forms would not clash, despite being duplicates.
In the example, the #OpenWin2 constant from win1 is simply a custom event, assigned the first custom value, #PB_Event_FirstCustomValue. So, when posted with the PostEvent() function from win1, the event loop of the mainApp would be able to read it.
Code: Select all
...
...
Repeat
event = WaitWindowEvent()
Select event
Case win1::#OpenWin2 ; <--- detecting the custom event posted from win1
...
...
There is one exception to the module's blackboxing property. Object numbers transcend these namespaces, as they are universal, and thus accessible from any namespace.
For example, in this dynamic object numbering approach, two or more forms can have buttons called Button_0,
Code: Select all
Button_0 = ButtonGadget(#PB_Any, 10, 10, 100, 30, "Button")
However, if an object is defined statically like this, the object with the number [0] is universal across all code and modules.
Code: Select all
ButtonGadget(0, 10, 10, 100, 30, "Button")
Anyway, modules provide a sound and simple approach to keeping forms and code separate while handling multi-form projects.
PureBasic is very powerful in its own unique ways, and it shouldn't be compared to other development environments.
Learn it and use it, and you'll love it.
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: How to open and reopen a window from a first window?
Thanks for clarifying TI-994A
I will dive deeper into modules.
Already in love with PureBasic.
But after a long marriage...
Greetings from Belgium
Rudi
I will dive deeper into modules.
Already in love with PureBasic.
But after a long marriage...
Greetings from Belgium
Rudi

