Page 1 of 2

Multiple window event handling?

Posted: Sun Sep 03, 2006 11:23 pm
by Shannara
I have PB 4 with newest libs, yadda yadda, etc. Whenever there is more then one window in my application, it only catches events for the first window checked when comparing EventWindow().
It displays the other windows but refuse to catch it's events. Is there a command to force PB to catch events for other windows?

Posted: Sun Sep 03, 2006 11:35 pm
by Joakim Christiansen
Are you doing something like this and it dosen't work? :?

Code: Select all

WindowEvent = WaitWindowEvent()

Select EventWindow()
  Case #Window1
    Select WindowEvent
      Case #PB_Event_CloseWindow
        End
    EndSelect
  Case #Window2
    Select WindowEvent
      Case #PB_Event_CloseWindow
        End
    EndSelect
EndSelect

Posted: Mon Sep 04, 2006 2:16 am
by Shannara
Yep, thats basically it. All the events of window1 is captured, however, window2 events are never captured.

However, if you move window2 event handling above window1, then the opposite occurs. Window 2 events fire, but window1 events will not fire.

Posted: Mon Sep 04, 2006 5:46 am
by Rescator
Must be your code Shannara, this (very quick/dirty/slapped together example) works just fine.

My advice is, enumerate ALL gadgets for all windows in same enumeration,
same for menus.
And when possible start enumerations at 1 rather than the default 0.

i.e:

Enumeration 1
Window_1
Window_2
EndEnumeration

Enumeration 1
Gadget_1 ;win1
Gadget_2 ;win1
Gadget_3 ;win2
Gadget_4 ;win2
EndEnumeration

Enumeration 1
Menu_1 ;you get the point I hope.
EndEnumeration

This makes it a lot easier to debug,
if your events return 0 then you know something is odd
as you'd haev no window/gadget/menu that is 0.
Or you'd easily see the gadget number returned but notice it's for the wrong window etc.

PS! All events is gathered at start of the loop,
may be more efficient (for the loop) to plase some of the event gathering inside the selects where appropriate instead!

Code: Select all

OpenWindow(1, 0, 0, 230, 90, "Event handling example...1", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

   If CreateGadgetList(WindowID(1))
     ButtonGadget  (1, 10, 10, 200, 20, "Click me")
     CheckBoxGadget(2, 10, 40, 200, 20, "Check me")
   EndIf

   If CreateMenu(1, WindowID(1))
     MenuTitle("Menu")
     MenuItem(1, "Item 1")
     MenuItem(2, "Item 2")
     MenuItem(3, "Item 3")
   EndIf

OpenWindow(2, 0, 0, 230, 90, "Event handling example...2", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

   If CreateGadgetList(WindowID(2))
     ButtonGadget  (3, 10, 10, 200, 20, "Click me")
     CheckBoxGadget(4, 10, 40, 200, 20, "Check me")
   EndIf

   If CreateMenu(2, WindowID(2))
     MenuTitle("Menu")
     MenuItem(4, "Item 1")
     MenuItem(5, "Item 2")
     MenuItem(6, "Item 3")
   EndIf

Repeat
 Event = WaitWindowEvent()
 Window = EventWindow()
 Gadget = EventGadget()
 Menu = EventMenu()
 Select Window
   Case 1
     Select Event
       Case #PB_Event_Gadget
         Select Gadget
           Case 1 : Debug "Win1 Button 1 clicked!"
           Case 2 : Debug "Win1 Button 2 clicked!"
         EndSelect
       Case #PB_Event_Menu
         Select Menu
           Case 1 : Debug "Win1 Menu item 1 clicked!"
           Case 2 : Debug "Win1 Menu item 2 clicked!"
           Case 3 : Debug "Win1 Menu item 3 clicked!"
         EndSelect
       Case #PB_Event_CloseWindow
         End
     EndSelect
   Case 2
     Select Event
       Case #PB_Event_Gadget
         Select Gadget
           Case 3 : Debug "Win2 Button 1 clicked!"
           Case 4 : Debug "Win2 Button 2 clicked!"
         EndSelect
       Case #PB_Event_Menu
         Select Menu
           Case 4 : Debug "Win2 Menu item 1 clicked!"
           Case 5 : Debug "Win2 Menu item 2 clicked!"
           Case 6 : Debug "Win2 Menu item 3 clicked!"
         EndSelect
       Case #PB_Event_CloseWindow
         End
     EndSelect
 EndSelect

Until Event = #PB_Event_CloseWindow

Posted: Mon Sep 04, 2006 8:08 am
by blueznl
same way i do it :-)

Posted: Mon Sep 04, 2006 10:09 am
by newbie
I do a single whole enumeration for all gadgets, this way eveything has necessarily a different number, and my two windows work fine :)

Posted: Mon Sep 04, 2006 10:34 am
by Dare
Rescator wrote:My advice is, enumerate ALL gadgets for all windows in same enumeration, same for menus. And when possible start enumerations at 1 rather than the default 0.
Spot on.

Posted: Mon Sep 04, 2006 2:47 pm
by SoulReaper
Thats the Way To Do It :wink:

Posted: Mon Sep 04, 2006 4:23 pm
by Rescator
Here is a better example, and the way I'd advice to do really large projects.

Code: Select all

EnableExplicit

#Window_1=1000
#Window_2=2000

Enumeration
 #Gadget_1_ClickMe=#Window_1+1
 #Gadget_1_CheckMe
 #Gadget_2_ClickMe=#Window_2+1
 #Gadget_2_CheckMe
EndEnumeration

Enumeration
 #Menu_1_Item1=#Window_1+1
 #Menu_1_Item2
 #Menu_1_Item3
 #Menu_2_Item1=#Window_2+1
 #Menu_2_Item2
 #Menu_2_Item3
EndEnumeration

If OpenWindow(#Window_1, 200, 50, 230, 90, "Event handling example...1", #PB_Window_SystemMenu)

 If CreateGadgetList(WindowID(#Window_1))
   ButtonGadget  (#Gadget_1_ClickMe, 10, 10, 200, 20, "Click me")
   CheckBoxGadget(#Gadget_1_CheckMe, 10, 40, 200, 20, "Check me")
 EndIf
 
 If CreateMenu(#Window_1, WindowID(#Window_1))
   MenuTitle("Menu")
   MenuItem(#Menu_1_Item1, "Item 1")
   MenuItem(#Menu_1_Item2, "Item 2")
   MenuItem(#Menu_1_Item3, "Item 3")
 EndIf
Else
 End
EndIf

If OpenWindow(#Window_2, 200, 200, 230, 90, "Event handling example...2", #PB_Window_SystemMenu)

 If CreateGadgetList(WindowID(#Window_2))
   ButtonGadget  (#Gadget_2_ClickMe, 10, 10, 200, 20, "Click me")
   CheckBoxGadget(#Gadget_2_CheckMe, 10, 40, 200, 20, "Check me")
 EndIf
 
 If CreateMenu(#Window_2, WindowID(#Window_2))
   MenuTitle("Menu")
   MenuItem(#Menu_2_Item1, "Item 1")
   MenuItem(#Menu_2_Item2, "Item 2")
   MenuItem(#Menu_2_Item3, "Item 3")
 EndIf

Else
 End
EndIf

Define.l Event,Window,Gadget,Menu

Repeat
 Event = WaitWindowEvent()
 If Event : Window = EventWindow() : EndIf
 Select Window
   Case #Window_1
     Select Event
       Case #PB_Event_Gadget
         Gadget = EventGadget()
         Select Gadget
           Case #Gadget_1_ClickMe : Debug "Win1 Button 1 clicked!"
           Case #Gadget_1_CheckMe : Debug "Win1 Button 2 clicked!"
         EndSelect
       Case #PB_Event_Menu
         Menu = EventMenu()
         Select Menu
           Case #Menu_1_Item1 : Debug "Win1 Menu item 1 clicked!"
           Case #Menu_1_Item2 : Debug "Win1 Menu item 2 clicked!"
           Case #Menu_1_Item3: Debug "Win1 Menu item 3 clicked!"
         EndSelect
       Case #PB_Event_CloseWindow
         End
     EndSelect
   Case #Window_2
     Select Event
       Case #PB_Event_Gadget
         Gadget = EventGadget()
         Select Gadget
           Case #Gadget_2_ClickMe : Debug "Win2 Button 1 clicked!"
           Case #Gadget_2_CheckMe : Debug "Win2 Button 2 clicked!"
         EndSelect
       Case #PB_Event_Menu
         Menu = EventMenu()
         Select Menu
           Case #Menu_2_Item1 : Debug "Win2 Menu item 1 clicked!"
           Case #Menu_2_Item2 : Debug "Win2 Menu item 2 clicked!"
           Case #Menu_2_Item3 : Debug "Win2 Menu item 3 clicked!"
         EndSelect
       Case #PB_Event_CloseWindow
         End
     EndSelect
 EndSelect

Until Event = #PB_Event_CloseWindow

Posted: Mon Sep 04, 2006 4:38 pm
by Shannara
Thanks guys. I narrowed it down. Basically I am using #PB_ANY so the program can be expanded without recompiling. One of the things is, when I am done with a window (not ending the program), I CloseWindow() it.

When that happens, PB closes the window, but will not catch any of the other window's events. So I figured that part of PB isnt complete yet. I tried out the HideWindow() command, however, even with hide window, PB will automatically fire events for that window (is this by design?).

Any how, I narrowed it down with EventType, and catching events that way. Thanks for the help guys!

Posted: Mon Sep 04, 2006 4:52 pm
by Rescator
As for getting events even if the window is hidden, yes.
That is a requirement if not the OS (Windows at least) message queue would be slowed down.
PS! A hidden window is how windowless programs is able to have a message queue if I recall correctly.

Btw! You might wanna rethink the way you do your windows,
seems to me the culprit is #PB_Any.

The following example (based on the above) let you close either window,
the program will not quit until both windows are closed.
There is no issues with a window getting messages afterwards.

So I can only guess it's the way you use #PB_Any,
could you give a example with your window management code,
somebody here might be able to spot your bug and give a solution.

Code: Select all

EnableExplicit

#Window_1=1000
#Window_2=2000

Enumeration
 #Gadget_1_ClickMe=#Window_1+1
 #Gadget_1_CheckMe
 #Gadget_2_ClickMe=#Window_2+1
 #Gadget_2_CheckMe
EndEnumeration

Enumeration
 #Menu_1_Item1=#Window_1+1
 #Menu_1_Item2
 #Menu_1_Item3
 #Menu_2_Item1=#Window_2+1
 #Menu_2_Item2
 #Menu_2_Item3
EndEnumeration

If OpenWindow(#Window_1, 200, 50, 230, 90, "Event handling example...1", #PB_Window_SystemMenu)

 If CreateGadgetList(WindowID(#Window_1))
   ButtonGadget  (#Gadget_1_ClickMe, 10, 10, 200, 20, "Click me")
   CheckBoxGadget(#Gadget_1_CheckMe, 10, 40, 200, 20, "Check me")
 EndIf
 
 If CreateMenu(#Window_1, WindowID(#Window_1))
   MenuTitle("Menu")
   MenuItem(#Menu_1_Item1, "Item 1")
   MenuItem(#Menu_1_Item2, "Item 2")
   MenuItem(#Menu_1_Item3, "Item 3")
 EndIf
Else
 End
EndIf

If OpenWindow(#Window_2, 200, 200, 230, 90, "Event handling example...2", #PB_Window_SystemMenu)

 If CreateGadgetList(WindowID(#Window_2))
   ButtonGadget  (#Gadget_2_ClickMe, 10, 10, 200, 20, "Click me")
   CheckBoxGadget(#Gadget_2_CheckMe, 10, 40, 200, 20, "Check me")
 EndIf
 
 If CreateMenu(#Window_2, WindowID(#Window_2))
   MenuTitle("Menu")
   MenuItem(#Menu_2_Item1, "Item 1")
   MenuItem(#Menu_2_Item2, "Item 2")
   MenuItem(#Menu_2_Item3, "Item 3")
 EndIf

Else
 End
EndIf

Define.l Event,Window,Gadget,Menu

Repeat
 Event = WaitWindowEvent()
 If Event : Window = EventWindow() : EndIf
 Select Window
   Case #Window_1
     Select Event
       Case #PB_Event_Gadget
         Gadget = EventGadget()
         Select Gadget
           Case #Gadget_1_ClickMe : Debug "Win1 Button 1 clicked!"
           Case #Gadget_1_CheckMe : Debug "Win1 Button 2 clicked!"
         EndSelect
       Case #PB_Event_Menu
         Menu = EventMenu()
         Select Menu
           Case #Menu_1_Item1 : Debug "Win1 Menu item 1 clicked!"
           Case #Menu_1_Item2 : Debug "Win1 Menu item 2 clicked!"
           Case #Menu_1_Item3: Debug "Win1 Menu item 3 clicked!"
         EndSelect
       Case #PB_Event_CloseWindow
         CloseWindow(#Window_1)
         If IsWindow(#Window_2) : Event=0 : EndIf
     EndSelect
   Case #Window_2
     Select Event
       Case #PB_Event_Gadget
         Gadget = EventGadget()
         Select Gadget
           Case #Gadget_2_ClickMe : Debug "Win2 Button 1 clicked!"
           Case #Gadget_2_CheckMe : Debug "Win2 Button 2 clicked!"
         EndSelect
       Case #PB_Event_Menu
         Menu = EventMenu()
         Select Menu
           Case #Menu_2_Item1 : Debug "Win2 Menu item 1 clicked!"
           Case #Menu_2_Item2 : Debug "Win2 Menu item 2 clicked!"
           Case #Menu_2_Item3 : Debug "Win2 Menu item 3 clicked!"
         EndSelect
       Case #PB_Event_CloseWindow
         CloseWindow(#Window_2)
         If IsWindow(#Window_1) : Event=0 : EndIf
     EndSelect
 EndSelect

Until Event = #PB_Event_CloseWindow

Posted: Mon Sep 04, 2006 5:12 pm
by Trond
Problem: WindowEvent() doesn't work very well.

Code: Select all

MainWindow = OpenWindow(#PB_Any, 0, 0, 512, 384, "")
Repeat
  Event = WaitWindowEvent()
  Debug WindowEvent()
ForEver

Posted: Mon Sep 04, 2006 6:26 pm
by John Bedlam
Trond wrote:Problem: WindowEvent() doesn't work very well.

Code: Select all

MainWindow = OpenWindow(#PB_Any, 0, 0, 512, 384, "")
Repeat
  Event = WaitWindowEvent()
  Debug WindowEvent()
ForEver
You're dropping half the events.

Posted: Mon Sep 04, 2006 6:29 pm
by netmaestro
@trond: Do you mean EventWindow()? as WindowEvent() is inappropriate in the same loop as WaitWindowEvent().

Posted: Mon Sep 04, 2006 6:30 pm
by Trond
netmaestro wrote:@trond: Do you mean EventWindow()? as WindowEvent() is inappropriate in the same loop as WaitWindowEvent().
Uh. Yes. I thought it was weird I hadn't noticed until now.