I need code that demonstrates how to switch between independent windows.

Just starting out? Need help? Post your questions and find answers here.
Jan2004
Enthusiast
Enthusiast
Posts: 184
Joined: Fri Jan 07, 2005 7:17 pm

I need code that demonstrates how to switch between independent windows.

Post by Jan2004 »

I need code that demonstrates how to switch between independent windows.
I have three simple windows (as a demo of the problem I'm solving): the first, the welcome window – this will be the entrance to the program. Then, window number 2, where specific actions will be performed, and window number 3, where other tasks will be performed.
I want to achieve the following three important goals:
1. The welcome window appears for 5 seconds.
2. Then, window number 2 or window number 3 opens, depending on the user's settings. The welcome window disappears after performing its welcome function.
3. Then, when I launch the window I selected earlier in the settings, for example, window number 2, I want to be able to switch between windows: in window 2, I press the button: "I want to go to window 3" and then window 2 will disappear, and window number 3 will appear. And vice versa: in window 3, I have the button "Go back to window 2" and then window 3 should disappear, and window 2 should appear.
As always, I'm counting on constructive ideas from colleagues more talented than me, for which I sincerely thank you in advance.

Code: Select all

;the_welcome_window.pb

Procedure the_welcome_window()

If OpenWindow(0, 100, 200, 400, 200, "the welcome window", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
  Global   hisNamea$,  place_he_she_lives$
  hisNamea$ = "Very nice user of my program"
  place_he_she_lives$ = "Interesting town"
  
  If LoadFont(1, "Arial", 24)
      TextGadget(2, 120,  40, 200, 50, "My software")
      SetGadgetFont(2, FontID(1))
    EndIf

  
  TextGadget(3, 15,  130, 153, 20, "version 1.1")
  TextGadget(4, 300, 130, 253,20, Chr(169) + " John Porter")
  TextGadget(5, 10, 160, 380, 20,"Program user: "+hisNamea$ + ", "+place_he_she_lives$ )
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
            
        EndSelect      
    EndSelect    
  Until Quit = 1
  
EndIf
EndProcedure
the_welcome_window()


;window_number_2.pb

Procedure window_number_2()

If OpenWindow(10, 100, 200, 300, 350, "window number 2", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)

  If LoadFont(11, "Arial", 24)
      TextGadget(12, 25,  40, 300, 50, "window number 2")
      SetGadgetFont(12, FontID(11))
    EndIf

  ButtonGadget(13, 55, 250, 190, 30, "I want To go To window 3")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
            
        EndSelect      
    EndSelect    
  Until Quit = 1
  
EndIf
EndProcedure
window_number_2()

;window_number_3.pb

Procedure window_number_3()

If OpenWindow(20, 100, 200, 500, 250, "window number 3", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)

  
  If LoadFont(21, "Arial", 24)
      TextGadget(22, 125,  40, 300, 50, "window number 3")
      SetGadgetFont(22, FontID(21))
    EndIf

  ButtonGadget(23, 155, 150, 190, 30, "Go back to window 2")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
            
        EndSelect      
    EndSelect    
  Until Quit = 1
  
EndIf
EndProcedure
 window_number_3()


User avatar
JHPJHP
Addict
Addict
Posts: 2279
Joined: Sat Oct 09, 2010 3:47 am

Re: I need code that demonstrates how to switch between independent windows.

Post by JHPJHP »

Removed; post ignored.
Last edited by JHPJHP on Fri Nov 21, 2025 3:49 am, edited 2 times in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
TI-994A
Addict
Addict
Posts: 2772
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: I need code that demonstrates how to switch between independent windows.

Post by TI-994A »

Jan2004 wrote: Tue Nov 18, 2025 4:23 pmI want to achieve the following three important goals:
1. The welcome window appears for 5 seconds.
2. Then, window number 2 or window number 3 opens, depending on the user's settings. The welcome window disappears after performing its welcome function.
3. Then, when I launch the window I selected earlier in the settings, for example, window number 2, I want to be able to switch between windows...
Here's an alternative to opening and closing the windows repeatedly. It instantiates each window only once and subsequently shows and hides them accordingly. Simplified for clarity.

Code: Select all

Global welcome, welcomeTimer, win2, win3, win2Button, win3Button

firstWindowConfig = 2

Procedure the_welcome_window()  
  welcome = OpenWindow(#PB_Any, 0, 0, 400, 200, "Welcome Window", #PB_Window_Tool | #PB_Window_ScreenCentered)    
  TextGadget(0, 0, 70, 400, 30, "This window will close in 5 seconds...", #PB_Text_Center)      
  AddWindowTimer(welcome, welcomeTimer, 5000)
EndProcedure

Procedure window_number_2()  
  win2 = OpenWindow(#PB_Any, 0, 0, 300, 350, "Window 2", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)       
  win2Button = ButtonGadget(#PB_Any, 55, 250, 190, 30, "show Window 3")      
EndProcedure

Procedure window_number_3()  
  win3 = OpenWindow(#PB_Any, 0, 0, 500, 250, "Window 3", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)        
  win3Button = ButtonGadget(#PB_Any, 155, 150, 190, 30, "show Window 2")      
  
EndProcedure

the_welcome_window()

Repeat
  Select WaitWindowEvent()      
    Case #PB_Event_Timer
      Select EventTimer()
        Case welcomeTimer
          CloseWindow(welcome)
          If firstWindowConfig = 2
            window_number_2()
          Else
            window_number_3()
          EndIf
      EndSelect         
    Case #PB_Event_Gadget
      Select EventGadget()
        Case win2Button
          HideWindow(win2, #True)
          If IsWindow(win3)
            HideWindow(win3, #False)
          Else
            window_number_3()
          EndIf          
        Case win3Button
          HideWindow(win3, #True)
          If IsWindow(win2)
            HideWindow(win2, #False)
          Else
            window_number_2()
          EndIf          
      EndSelect          
    Case #PB_Event_CloseWindow
      appQuit = #True
  EndSelect    
Until appQuit
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 :D
Jan2004
Enthusiast
Enthusiast
Posts: 184
Joined: Fri Jan 07, 2005 7:17 pm

Re: I need code that demonstrates how to switch between independent windows.

Post by Jan2004 »

I apologize for the slight delay in responding to your posts. Thank you, JHPJHP, and TI-994A, for your suggestions. JHPJHP, as always, presented world-class solutions. (Your achievement of this world-class standard was made possible by the existence of the PureBasic environment.) I'll be interested in reviewing the new versions of your codes when you re-release them, as you stated in another post:
viewtopic.php?t=87872
Then, I think, I'll have more time to analyze the codes, as some of my issues will be resolved.
Both of your examples were inspiring. I used them. However, my program intro doesn't have to be as "fancy" (so sophisticated) as JHPJHP's example. I also want the window management to be separate for each window. Why: one window in my program will have dozens of gadgets, and there will be four windows. If there were one management center for all the windows, I would definitely get lost. If each window has its own management file for that window, I'll figure it out, though not without some intellectual effort.
Here's my suggestion for three windows. Four files are shown. Name them after the suggestion at the top of the window code. Run the intro and take a look at the solution. Then, please share your feedback, not just from JHPJHP and the TI-994A, but from all users of this forum (those who are willing, of course).

Code: Select all

Declare the_welcome_window()
Declare window_number_1()
Declare window_number_2()
Declare window_number_3()

;the_welcome_window.pb

Procedure the_welcome_window()
  
  If OpenWindow(0, 100, 200, 400, 200, "the welcome window", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
    AddWindowTimer(0, 123, 2000)
    Global   hisNamea$,  place_he_she_lives$
    hisNamea$ = "Very nice user of my program"
    place_he_she_lives$ = "Interesting town"
    
    If LoadFont(1, "Arial", 24)
      TextGadget(2, 120,  40, 200, 50, "My software")
      SetGadgetFont(2, FontID(1))
    EndIf
    
    TextGadget(3, 15,  130, 153, 20, "version 1.1")
    TextGadget(4, 300, 130, 253,20, Chr(169) + " John Porter")
    TextGadget(5, 10, 160, 380, 20,"Program user: "+hisNamea$ + ", "+place_he_she_lives$ )
    
    Repeat
      Event = WaitWindowEvent()
      
      If Event = #PB_Event_Timer And EventTimer()
        Event = #PB_Event_CloseWindow
        ; CloseWindow(0)
      EndIf    
      
    Until Event = #PB_Event_CloseWindow
  EndIf
EndProcedure



;window_number_1.pb

Procedure window_number_1()
  
  If OpenWindow(10, 100, 200, 300, 350, "window number 1", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
    
    If LoadFont(11, "Arial", 24)
      TextGadget(12, 25,  40, 300, 50, "window number 1")
      SetGadgetFont(12, FontID(11))
    EndIf
    
    ButtonGadget(13, 55, 250, 190, 30, "Go to window 2")
    ButtonGadget(14, 55, 300, 190, 30, "Go to window 3")
    ; HideWindow(10, #True)
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Quit = 1
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 13
              CloseWindow(10)
              window_number_2()
            Case 14
              CloseWindow(10)
              window_number_3()   
          EndSelect      
      EndSelect    
    Until Quit = 1
    If Quit = 1
      CloseWindow(10)
      EndIf
  EndIf
EndProcedure


;window_number_2.pb

Procedure window_number_2()
  
  If OpenWindow(20, 100, 200, 500, 500, "window number 2", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
    
    
    If LoadFont(21, "Arial", 24)
      TextGadget(22, 125,  40, 300, 50, "window number 2")
      SetGadgetFont(22, FontID(21))
    EndIf
    
    ButtonGadget(23, 155, 350, 190, 30, "Go to window 1")
    ButtonGadget(24, 155, 400, 190, 30, "Go to window 3")
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Quit = 1
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 23
              CloseWindow(20)
              window_number_1()
            Case 24
              CloseWindow(20)
              window_number_3()   
          EndSelect      
      EndSelect    
    Until Quit = 1
        If Quit = 1
      CloseWindow(20)
      EndIf
  EndIf
EndProcedure



Procedure window_number_3()
  
  If OpenWindow(30, 100, 200, 500, 250, "window number 3", #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
    
    
    If LoadFont(31, "Arial", 24)
      TextGadget(32, 125,  40, 300, 50, "window number 3")
      SetGadgetFont(32, FontID(31))
    EndIf
    
    ButtonGadget(33, 155, 120, 190, 30, "Go to window 1")
    ButtonGadget(34, 155, 170, 190, 30, "Go to window 2")
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Quit = 1
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 33
              CloseWindow(30)
              window_number_1()
            Case 34
              CloseWindow(30)
              window_number_2()
          EndSelect      
      EndSelect    
    Until Quit = 1
        If Quit = 1
      CloseWindow(30)
      EndIf
  EndIf
EndProcedure


Global.i Setting_the_window_number  ;This will be in the settings: which window should be shown As the opening window
Setting_the_window_number = 3

the_welcome_window()
CloseWindow(0)

Select Setting_the_window_number
  Case 1
    window_number_1()
  Case 2
    window_number_2()
  Case 3
    window_number_3()
EndSelect

benubi
Enthusiast
Enthusiast
Posts: 236
Joined: Tue Mar 29, 2005 4:01 pm

Re: I need code that demonstrates how to switch between independent windows.

Post by benubi »

There's a "bad" style when using multiple event loops like that, and calling the window_xyz procedures recursively. There's also a problem when I close the "wrong" window.

You can open the windows with the hidden flag in the background. Then you only need to switch visibility. You can also use ActivateWindow(#window), that window will be active (have the focus) and should be brought to the top in case it was in the back. There's also the possibility to pin the window, but that's not strictly necessary - could be wanted if you want to have something that behaves like a dialog.

To demonstrate the "problem" 1. use the debugger, click a lot of times between the go to window_xyz, say a dozen of times.

2. Then go in the PureBasic IDE menu and click on Debugger/Callstack. There you can see that the stack is growing and growing, which can lead to stack overflow after a few thousand times (not millions). Because the procedures never return, but call the next window_xyz procedure. (They only return once a window was closed via close-button 'X').

I suggest to set the window opening flags with hidden attribute, and then use a single event loop that first hides all unwanted windows, and then shows the single wanted window using HideWindow().
Jan2004
Enthusiast
Enthusiast
Posts: 184
Joined: Fri Jan 07, 2005 7:17 pm

Re: I need code that demonstrates how to switch between independent windows.

Post by Jan2004 »

benubi. Thank you for your valuable criticism. Could you please suggest some PureBasic code for your last paragraph: "I suggest setting the window opening flags with the hidden attribute, and then using a single event loop that first hides all unwanted windows, and then shows the single desired window using HideWindow()."
Thanks in advance.
Olli
Addict
Addict
Posts: 1272
Joined: Wed May 27, 2020 12:26 pm

Re: I need code that demonstrates how to switch between independent windows.

Post by Olli »

JHPJHP wrote: Tue Nov 18, 2025 5:12 pm Removed; post ignored.
If it is removed, sure it will be ignored...
User avatar
TI-994A
Addict
Addict
Posts: 2772
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: I need code that demonstrates how to switch between independent windows.

Post by TI-994A »

Hello again, @Jan2004.

As most have highlighted, multiple calls to the WaitWindowEvent() function is not recommended. Even if your modal windows are in separate code files, they will be integrated into the calling code and should thus merge with its main event loop.

Alternatively, the binding functions would serve your requirements quite nicely. They could be contained along with their window procedures into separate files and be called as required.

Here's another example to illustrate this approach.

Code: Select all

EnableExplicit

Declare the_welcome_window()
Declare welcomeWin_timer_handler()

Declare window_number_1()
Declare win1_gadget_handler()


Declare window_number_2()
Declare win2_gadget_handler()

Declare window_number_3()
Declare win3_gadget_handler()

Global Setting_the_window_number = 1


;the_welcome_window.pb

Procedure the_welcome_window()
  Global welcome_window, welcome_timer = 1
  Protected hisNamea.s, place_he_she_lives.s, welcome_text, welcome_font
  
  welcome_window = OpenWindow(#PB_Any, 0, 0, 400, 200, "the welcome window",
                              #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If welcome_window
    hisNamea = "Very nice user of my program"
    place_he_she_lives = "Interesting town"
    
    welcome_font = LoadFont(#PB_Any, "Arial", 24)
    welcome_text = TextGadget(#PB_Any, 120,  40, 200, 50, "My software")
    
    SetGadgetFont(welcome_text, FontID(welcome_font))
    TextGadget(#PB_Any, 15,  130, 153, 20, "version 1.1")
    TextGadget(#PB_Any, 300, 130, 253,20, Chr(169) + " John Porter")
    TextGadget(#PB_Any, 10, 160, 380, 20,"Program user: " + hisNamea + ", " + place_he_she_lives)
    
    AddWindowTimer(welcome_window, welcome_timer, 3000)
    BindEvent(#PB_Event_Timer, @welcomeWin_timer_handler(), welcome_window)
  EndIf  
EndProcedure

Procedure welcomeWin_timer_handler()
  Select EventTimer()
    Case welcome_timer  
      CloseWindow(welcome_window)
      Select Setting_the_window_number
        Case 1
          window_number_1()
        Case 2
          window_number_2()
        Case 3
          window_number_3()
      EndSelect      
  EndSelect  
EndProcedure


;window_number_1.pb

Procedure window_number_1()
  Global win1, win1_button1, win1_button2
  Protected win1_font, win1_text
  
  win1 = OpenWindow(#PB_Any, 0, 0, 300, 350, "window number 1", 
                    #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
  If win1
    win1_font = LoadFont(#PB_Any, "Arial", 24)
    win1_text = TextGadget(#PB_Any, 25,  40, 300, 50, "window number 1")
    SetGadgetFont(win1_text, FontID(win1_font))
    
    win1_button1 = ButtonGadget(#PB_Any, 55, 250, 190, 30, "Go to window 2")
    win1_button2 = ButtonGadget(#PB_Any, 55, 300, 190, 30, "Go to window 3")
    
    BindEvent(#PB_Event_Gadget, @win1_gadget_handler(), win1)  
  EndIf  
EndProcedure

Procedure win1_gadget_handler()
  Select EventGadget()
    Case win1_button1
      CloseWindow(win1)
      window_number_2()
    Case win1_button2
      CloseWindow(win1)
      window_number_3()   
  EndSelect        
EndProcedure


;window_number_2.pb

Procedure window_number_2()
  Global win2, win2_button1, win2_button2
  Protected win2_font, win2_text
  
  win2 = OpenWindow(#PB_Any, 0, 0, 500, 500, "window number 2", 
                    #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
  If win2      
    win2_font = LoadFont(#PB_Any, "Arial", 24)
    win2_text= TextGadget(#PB_Any, 125,  40, 300, 50, "window number 2")
    SetGadgetFont(win2_text, FontID(win2_font))    
    
    win2_button1 = ButtonGadget(#PB_Any, 155, 350, 190, 30, "Go to window 1")
    win2_button2 = ButtonGadget(#PB_Any, 155, 400, 190, 30, "Go to window 3")
    
    BindEvent(#PB_Event_Gadget, @win2_gadget_handler(), win2)     
  EndIf
EndProcedure

Procedure win2_gadget_handler()
  Select EventGadget()
    Case win2_button1
      CloseWindow(win2)
      window_number_1()
    Case win2_button2
      CloseWindow(win2)
      window_number_3()   
  EndSelect      
EndProcedure


;window_number_3.pb

Procedure window_number_3()
  Global win3, win3_button1, win3_button2
  Protected win3_text, win3_font
  
  win3 = OpenWindow(#PB_Any, 0, 0, 500, 250, "window number 3", 
                    #PB_Window_SystemMenu |#PB_Window_ScreenCentered)
  If win3     
    win3_font = LoadFont(#PB_Any, "Arial", 24)
    win3_text = TextGadget(#PB_Any, 125,  40, 300, 50, "window number 3")
    SetGadgetFont(win3_text, FontID(win3_font))    
    
    win3_button1 = ButtonGadget(#PB_Any, 155, 120, 190, 30, "Go to window 1")
    win3_button2 = ButtonGadget(#PB_Any, 155, 170, 190, 30, "Go to window 2")
    
    BindEvent(#PB_Event_Gadget, @win3_gadget_handler(), win3)   
  EndIf  
EndProcedure

Procedure win3_gadget_handler()
  Select EventGadget()
    Case win3_button1
      CloseWindow(win3)
      window_number_1()
    Case win3_button2
      CloseWindow(win3)
      window_number_2()
  EndSelect   
EndProcedure

the_welcome_window()

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend

Please note the following:

1. the welcome window contains only a window timer and no gadgets - so only the timer event is being handled.
2. the other three windows contain only gadgets - so only gadget events are handled for each of them.
3. since your requirement seems to be to terminate the application when any of the windows are closed, no special handling is required - the WaitWindowEvent() at the end of the code will handle that.
4. There are a number of other events that can be bound in a similar manner, and each should be handled accordingly.

Hope it helps. :wink:
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 :D
Jan2004
Enthusiast
Enthusiast
Posts: 184
Joined: Fri Jan 07, 2005 7:17 pm

Re: I need code that demonstrates how to switch between independent windows.

Post by Jan2004 »

Hello again, @TI-994A.

You absolutely, perfectly delivered what I dreamed of. Thank you so much. Best regards, and I wish you continued success.
Post Reply