why an event occurs gadget

Just starting out? Need help? Post your questions and find answers here.
mestnyi
Addict
Addict
Posts: 1102
Joined: Mon Nov 25, 2013 6:41 am

why an event occurs gadget

Post by mestnyi »

Code: Select all

win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
 
    ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
    CloseGadgetList()

      Repeat
    Select WaitWindowEvent()
         
   Case #PB_Event_Gadget
     Debug EventGadget() 
          Case #PB_Event_CloseWindow
                Quit = 1     
               
      EndSelect

    Until Quit = 1
    End
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: why an event occurs gadget

Post by luis »

Nice indentation. :)

The generated #PB_Event_Gadget looks like a bug to me.

Also EventGadget() returns -1.
help wrote: After an event of type #PB_Event_Gadget (returned by WindowEvent() or WaitWindowEvent()), use this function to determine which gadget has been triggered. It returns the #Gadget number.
There is no gadget with -1 as its number, and calling EventGadget() when no #PB_Event_Gadget is received (even if you shouldn't) seems to return 0.
So the -1 is probably just a consequence of the bug since there is no gadget number to set for EventGadget() (container is empty).
"Have you tried turning it off and on again ?"
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: why an event occurs gadget

Post by PB »

It's something to do with the ContainerGadget, because if you
remove that line (and also CloseGadgetList) and use another
gadget (like a ButtonGadget), no event occurs.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: why an event occurs gadget

Post by BorisTheOld »

mestnyi wrote:

Code: Select all

win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
 
    ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
    CloseGadgetList()

      Repeat
    Select WaitWindowEvent()
         
   Case #PB_Event_Gadget
     Debug EventGadget() 
          Case #PB_Event_CloseWindow
                Quit = 1     
               
      EndSelect

    Until Quit = 1
    End
You need to filter the events by checking for the correct window number. When I first started using PB I found that spurious events were being created in the event loop. Try the following code:

Code: Select all

win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
 
ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
CloseGadgetList()

Repeat
  iWindowEvent  = WaitWindowEvent()   ; get an event
  iWindowNumber = EventWindow()       ; get the window number of the event
  If iWindowNumber <> Win1
    Continue                          ; don't process this event                                       
  EndIf
  
  Select iWindowEvent
   Case #PB_Event_Gadget
     Debug EventGadget() 
   Case #PB_Event_CloseWindow
     Quit = 1     
  EndSelect

Until Quit = 1

End
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: why an event occurs gadget

Post by Danilo »

There are always many more events coming, and you just have to ignore them.

Code: Select all

win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)

ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
CloseGadgetList()

Repeat
    event = WaitWindowEvent()
    Debug event
Until event = #PB_Event_CloseWindow
Why should this be a bug?

Just check the events for your windows and gadgets, ignoring all other events:

Code: Select all

win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)

ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
CloseGadgetList()

Repeat
    Select WaitWindowEvent()
            
        Case #PB_Event_Gadget
            If EventGadget() = 5
                Debug EventType() ; event type for gadget 5
            EndIf
        Case #PB_Event_CloseWindow
            Quit = 1     
            
    EndSelect
    
Until Quit = 1
End
Has been like this for 15 years...
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: why an event occurs gadget

Post by PB »

> Just check the events for your windows and gadgets, ignoring all other events

Very true!
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
mestnyi
Addict
Addict
Posts: 1102
Joined: Mon Nov 25, 2013 6:41 am

Re: why an event occurs gadget

Post by mestnyi »

checks that can be done but I want to have legislation

Code: Select all

Procedure EventMouse(Gadget,Window=-1)
 Protected  x.l, y.l, w.l, h.l, mx.l, my.l
  Static OldGadget,NewGadget,wIn,gIn,IGadget
;-------------------------------     
   ;Координаты курсора заносим в переменные
   mx =DesktopMouseX() 
   my =DesktopMouseY()
   If IsGadget(Gadget) ;Если это гаджет то размеры гаджета заносим в переменные  
    x=GadgetX(Gadget,#PB_Gadget_ScreenCoordinate)
    y=GadgetY(Gadget,#PB_Gadget_ScreenCoordinate)
    w=GadgetWidth(Gadget)
    h=GadgetHeight(Gadget)
   EndIf
   If (mx >= x And mx <= (x+w) And my >= y And my <= (y+h)) ;Если указатель мыши нахотится на гаджете
     If gIn=#False And IGadget<>Gadget  :gIn=#True ;Если мы на форме
       ;Debug "from window"
       PostEvent(#PB_Event_Gadget,EventWindow(),Gadget, #PB_EventType_MouseEnter)
       IGadget=Gadget
       NewGadget=Gadget
       OldGadget=Gadget
     EndIf
     If NewGadget<>Gadget And IGadget=#False ;Если мы на гаджете
     ;Debug "from gadget"
      PostEvent(#PB_Event_Gadget,EventWindow(),Gadget, #PB_EventType_MouseEnter)
       NewGadget=Gadget
        If OldGadget<>NewGadget And gIn=#True;Указываем что мы на форме
        ;Debug "on gadget"
        PostEvent(#PB_Event_Gadget,EventWindow(),OldGadget, #PB_EventType_MouseLeave)
       OldGadget=NewGadget
      EndIf
     EndIf
   Else
     If IsGadget(NewGadget) ;Если это гаджет то размеры гаджета заносим в переменные  
      x=GadgetX(NewGadget,#PB_Gadget_ScreenCoordinate)
      y=GadgetY(NewGadget,#PB_Gadget_ScreenCoordinate)
      w=GadgetWidth(NewGadget)
      h=GadgetHeight(NewGadget)
     EndIf
     If (mx < x Or mx > (x+w) Or my < y Or my > (y+h)) ;Если указатель мыши нахотится за пределами гаджета
     If gIn=#True :gIn=#False ;Указываем что мы на форме
       ;Debug "on window"
       PostEvent(#PB_Event_Gadget,EventWindow(),newGadget, #PB_EventType_MouseLeave)
       IGadget=#False
       OldGadget=NewGadget
   EndIf
   
   EndIf
   
   EndIf
    
 EndProcedure


win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
     ButtonGadget(3,10,20,62,22,"" )
     ButtonGadget(4,50,20,62,22,"" )
        
        ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
        CloseGadgetList()

        Repeat
          EventMouse(3)
          EventMouse(4)
          EventMouse(5)
          
          Select WaitWindowEvent()
             
       Case #PB_Event_Gadget
         Debug EventGadget()
              Case #PB_Event_CloseWindow
                    Quit = 1     
                   
          EndSelect

        Until Quit = 1
        End
mestnyi
Addict
Addict
Posts: 1102
Joined: Mon Nov 25, 2013 6:41 am

Re: why an event occurs gadget

Post by mestnyi »

When eventgadget () returns 1, this will mean that the cursor is on the form, and so I have some troubles arise
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: why an event occurs gadget

Post by luis »

PB wrote:> Just check the events for your windows and gadgets, ignoring all other events

Very true!

Well, you are telling "very true" like it were necessarily wrong doing otherwise.

The doc says:
After an event of type #PB_Event_Gadget (returned by WindowEvent() or WaitWindowEvent()), use this function to determine which gadget has been triggered. It returns the #Gadget number.
If you get a #PB_Event_Gadget you MUST find the number of the gadget by calling EventGadget(), else the #PB_Event_Gadget shouldn't have been fired in the first place.

It shouldn't be needed to check for the window number like BorisTheOld does, if you need to check for that when you have only a window there is a bug in the logic PB follows to generate its custom #PB_ events. Even the examples in the PB manual don't do something like that, and for good reason. Shouldn't be needed.

You should use EventWindow() when you are using a single message loop to process the events for more than one PB window.

I agree with Danilo you should just check with eventgadget for the gadget numbers you expect to receive and nothing else, because usually it's the logical thing to do, but this doesn't change the fact the #PB_Event_Gadget shouldn't be fired if there is no valid gadget number to go with it. This is an event coming from where ? Why ? Why should be reported to me ? And why as a #PB_Event_Gadget when there is no gadget associated ?

Loos like a bug to me :wink:
"Have you tried turning it off and on again ?"
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: why an event occurs gadget

Post by BorisTheOld »

luis wrote:It shouldn't be needed to check for the window number like BorisTheOld does, if you need to check for that when you have only a window there is a bug in the logic PB follows to generate its custom #PB_ events. Even the examples in the PB manual don't do something like that, and for good reason. Shouldn't be needed.
At some point, though, it's necessary to check that the event is associated with a valid gadget. I've found that the cleanest way to do this is to reject any event that's not associated with a valid window. This is a lot faster, and uses less code, than trying to match the event to valid gadgets.

It's been 3 years since I first looked into this, and I can't remember the exact nature of the spurious events. But testing for a valid window seems to guarantee that all event and gadget references are valid.

By the way, I also save processing time by making use of the gadget data field to store a pointer to the associated gadget code. After filtering out unwanted events, I extract the gadget's data field and jump immediately to the gadget code, where I then analyze and process the event. Some of our applications have more than 3000 gadgets, so eliminating long chains of select statements from the event loop not only improves performance, but also improves maintainability.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Neil
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Feb 29, 2012 8:04 am
Location: Melbourne, AUS

Re: why an event occurs gadget

Post by Neil »

BorisTheOld wrote:
You need to filter the events by checking for the correct window number. When I first started using PB I found that spurious events were being created in the event loop. Try the following code:

Code: Select all

win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
 
ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
CloseGadgetList()

Repeat
  iWindowEvent  = WaitWindowEvent()   ; get an event
  iWindowNumber = EventWindow()       ; get the window number of the event
  If iWindowNumber <> Win1
    Continue                          ; don't process this event                                       
  EndIf
  
  Select iWindowEvent
   Case #PB_Event_Gadget
     Debug EventGadget() 
   Case #PB_Event_CloseWindow
     Quit = 1     
  EndSelect

Until Quit = 1

End
Isn't this like the example given by Polo for use with Form Designer where he checks for the window that generated the event

Code: Select all

Procedure Window_Main_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False
    Case #PB_Event_Gadget
      Debug EventGadget()      
  EndSelect
  ProcedureReturn #True
EndProcedure

OpenWindow_Main()

Repeat
  event = WaitWindowEvent()
  Select EventWindow()
    Case Window_Main      
      Window_Main_Events(event)
    Case Window_Secondary
      Window_Secondary_Events(event)
  EndSelect
Until Event = #PB_Event_CloseWindow Or bQuit = #True
i.e. Polo is agreeing that there should be a check for the window that generated the event.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: why an event occurs gadget

Post by luis »

Neil wrote: i.e. Polo is agreeing that there should be a check for the window that generated the event.
luis wrote: You should use EventWindow() when you are using a single message loop to process the events for more than one PB window.

Code: Select all

  Select EventWindow()
    Case Window_Main     ; one window ...
      Window_Main_Events(event)
    Case Window_Secondary ; ... two windows
      Window_Secondary_Events(event)
  EndSelec
"Have you tried turning it off and on again ?"
mestnyi
Addict
Addict
Posts: 1102
Joined: Mon Nov 25, 2013 6:41 am

Re: why an event occurs gadget

Post by mestnyi »

Code: Select all

Global Window_Main,Window_Secondary

Procedure OpenWindow_Secondary()
  Window_Main= OpenWindow(#PB_Any,0,0,400,300,"OpenWindow_Secondary", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
  ButtonGadget(13,10,20,62,22,"" )
     ButtonGadget(14,50,20,62,22,"" )
       
        ContainerGadget(15,10,220,62,22,#PB_Container_Flat )
        CloseGadgetList()
   EndProcedure



Procedure Window_Secondary_Events(event)
      Select event
        Case #PB_Event_CloseWindow
          ProcedureReturn #False
        Case #PB_Event_Gadget
          Debug EventGadget()     
      EndSelect
      ProcedureReturn #True
    EndProcedure
    
Procedure OpenWindow_Main()
  Window_Secondary= OpenWindow(#PB_Any,0,0,400,300,"OpenWindow_Main", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
    ButtonGadget(3,10,20,62,22,"" )
     ButtonGadget(4,50,20,62,22,"" )
       
        ContainerGadget(5,10,220,62,22,#PB_Container_Flat )
        CloseGadgetList()
 EndProcedure



Procedure Window_Main_Events(event)
      Select event
        Case #PB_Event_CloseWindow
          ProcedureReturn #False
        Case #PB_Event_Gadget
          Debug EventGadget()     
      EndSelect
      ProcedureReturn #True
    EndProcedure

    OpenWindow_Main()
    OpenWindow_Secondary()
    
    Repeat
      event = WaitWindowEvent()
      Select EventWindow()
        Case Window_Main     
          Window_Main_Events(event)
        Case Window_Secondary
          Window_Secondary_Events(event)
      EndSelect
    Until Event = #PB_Event_CloseWindow Or bQuit = #True
mestnyi
Addict
Addict
Posts: 1102
Joined: Mon Nov 25, 2013 6:41 am

Re: why an event occurs gadget

Post by mestnyi »

You tell me, all the same it is a bug or not a bug?

Code: Select all

  win1 = OpenWindow(#PB_Any,0,0,400,300,"Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered| #PB_Window_SizeGadget)
  ContainerGadget(5,10,220,62,22,#PB_Container_Flat ) :CloseGadgetList()
  Repeat
        Select WaitWindowEvent()
         Case #PB_Event_Gadget
           Debug EventGadget()
         Case #PB_Event_CloseWindow
           Quit = 1     
         EndSelect
  Until Quit = 1
  End
mestnyi
Addict
Addict
Posts: 1102
Joined: Mon Nov 25, 2013 6:41 am

Re: why an event occurs gadget

Post by mestnyi »

Code: Select all

OpenWindow(1, 358, 178, 300, 275, " Test ResizeWindow (Module)",  #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
         
   EditorGadget(37, 5, 35, 45, 85)      
  Repeat
      event = WaitWindowEvent()
     If event=#PB_Event_Gadget
     Debug EventGadget()
     EndIf
    Until Event = #PB_Event_CloseWindow

Why events occur is also as it should be? :evil:
Post Reply