Page 1 of 1

popupmenu event checking problem

Posted: Mon May 12, 2003 1:47 pm
by Fangbeast
I use the following code to popup a predefined menu when a specific gadget is clicked; in this case a ListIconGadget; and this works.

Code: Select all

  Repeat
    EventID = WaitWindowEvent()
      Select EventID
       Case #PB_EventMenu
          Select EventMenuID() 
             Case #Mypopupevent1
             Case #Mypopupevent2
          EndSelect
       Case #PB_EventGadget
          Select EventGadgetID()
            Case #Gadget_searchreplace_listbox
              If EventType() = #PB_EventType_RightClick
                DisplayPopupMenu(#Popup_searchreplace, WindowID())
              EndIf
          EndSelect
      EndSelect
  Until EventID = #PB_Event_CloseWindow
End
Problem is that although the popup menu pops up where and when it should, the events themselves never get fired when selected from the popup menu and I do not know why.

All my constants for both a permanent menu and the popup menu are different (I debugged all the values). Can't think what it could be

Posted: Mon May 12, 2003 4:50 pm
by pel
Just curious -- what kind of events are you firing off under #Mypopupevent1 and 2? I stuck a messagerequester under each one and they both showed up when I clicked on the popup menu items (I also assumed the listbox is a listicongadget) ... :?

Wondering how this worked itself out

Posted: Sun Apr 12, 2009 5:56 pm
by rdority
Hi there,

I'm experiencing the same sort of thing! The popup menu appears but the individual items don't fire! :(

(Code snippet follows...)

Code: Select all

  ;- RIGHT MOUSE CLICK
  
If Event = #PB_Event_Gadget And (EventType = #PB_EventType_RightClick)
  
    Select GadgetID

      Case #Email:

debug "email"         ;THIS FIRES JUST FINE ! ! !

        menuRes = CreatePopupMenu(#PB_Any)      ; pop-up menu ...
      
        If menuRes
          menuPos = GetGadgetState(#Email)
          
            MenuItem(1, "Forward")      
            MenuItem(2, "Delete")      
          
            DisplayPopupMenu(menuRes,WindowID(w1)) ;POPUP APPEARS!!!
  
            Select WaitWindowEvent()     ; check for window events
              Case #PB_Event_Menu        ; an item of the popup-menu was clicked
                Select EventMenu()     ; get the clicked menu item...

                  Case 1 :
debug "case 1"                    ;THIS NEVER FIRES! ! !  :(
                  
                  ;code follows here

                  Case 2 :
debug "case 2"                    ;THIS NEVER FIRES! ! !  :(

                  ;code follows here
                    
                EndSelect ;EventMenu()
                
            EndSelect ;WaitWindowEvent()

        EndIf ;menuRes

    EndSelect ;GadgetID

EndIf   ;Event = #PB_Event_Gadget And (EventType = #PB_EventType_RightClick)

I see no one has commented on this post for quite some time so I assume it got resolved.

But again, how?

The really odd thing is these popup menus were working before and now are exhibiting this strange behavior.

Thanks all,
Roark

Posted: Sun Apr 12, 2009 6:15 pm
by srod
You really do not want to embed a PB event loop within another such loop; just continue to use the original loop.

The thing is that you should number your menu command# uniquely so that no pop-up menu shares the same command# as your main menu.

Try the following for size :

Code: Select all

menuRes = CreatePopupMenu(#PB_Any)
If menuRes 
  MenuItem(1, "Forward")      
  MenuItem(2, "Delete")      
EndIf

If OpenWindow(0, 100, 150, 195, 260, "PureBasic - Menu")
  ButtonGadget(1, 10, 10, 100, 20, "Click!")

  Repeat

    Select WaitWindowEvent()

      Case #PB_Event_Gadget
          
        If menuRes 
          DisplayPopupMenu(menuRes,WindowID(0))
        EndIf  

      Case #PB_Event_Menu
        Select EventMenu() 
          Case 1 
            Debug "case 1"
          Case 2 
            Debug "case 2"
        EndSelect ;EventMenu() 
                
      Case #PB_Event_CloseWindow
        Quit = 1

    EndSelect

  Until Quit = 1

EndIf

The problem persists, but thanks for your reply..

Posted: Sun Apr 12, 2009 7:16 pm
by rdority
Thanks for your reply.

I tried setting it up the way you recommended (sticking with the one loop) but it does not seem to make a difference.

I still get the popup menu no problem, but the events do not fire. Very strange!
You really do not want to embed a PB event loop within another such loop; just continue to use the original loop.
I did not come up with this approach on my own but I liked it because it was modal which is exactly how I wnated my popup menu to work.

I never had an issue in my other PureBasic project with this approach.

In fact it was working fine in this project until last night when I turned on the "always show selected row" feature in the Visual designer. I will try turning that off and hope for the best!

Happy Sunday! :)

Again, thanks for your reply,
Roark

Posted: Sun Apr 12, 2009 7:19 pm
by srod
If the code I posted does not work for you then there is something very wrong with your system! :)

Popup Menu Now Works!

Posted: Sun Apr 12, 2009 10:03 pm
by rdority
I did not try your code on its own because I'm sure it does work when kept the way it is.

But when I tried to implement it such that it was all in the main loop, things didn't improve.

So it must be some sort of side effect from using the ListIcon gadget (or some option like the one that allows the entire row to be selected) because in my other project which uses a ListView gadget instead never has an issue with the code I pasted earlier.

I can appreciate your not recommending the inner event loop (merely for the popup menu).

Despite this, when I noticed that I didn't really have a Repeat .. Until loop, I went ahead and introduced it so that the inner loop would continue looping until a Menu Event occurred.

Things started working, but sure enough you were right. I discovered that if a user Cancels the Popup Menu by clicking off of it (not making a selection), the menu goes away but then the program is stuck in the inner loop! Thus the user can't click the close button, etc.

I was about to remove the inner event loop but I really like it because it makes it possible for me to confine the menu choices to 1, 2, 3, ... thus I don't have to use the Enumeration .. EndEnumeration or anything fancy to ensure that I'm using unique menu item #'s etc.

Keep in mind that everything worked. The only caveat was that if the user doesn't make a choice and clicks off the menu, it goes away and the program gets stuck in the inner loop!

So I got to thinking. What if I had a timer? But that seemed a little bit much.

So I used a counter! I now Repeat .. Until a menu event occurs, or the counter reaches a specific value.

This gives inner event loop enough time to determine which choice the user selected from the popup menu but it also ensures that control is returned to the outer (main) event loop just as soon as the popup menu disappears!

Here's the code snippet:
In this case the gadget is a ListIcon gadget with many rows of emails listed...

Code: Select all

  If Event = #PB_Event_Gadget And (EventType = #PB_EventType_RightClick)
  
    Select GadgetID

      Case #Email:

        menuRes = CreatePopupMenu(#PB_Any)  ;pop-up menu...
      
        If menuRes
          menuPos = GetGadgetState(#Email) ;get which row is involved

          ;make sure row clicked on has content!
          If menuPos > -1 And menuPos < CountGadgetItems(#Email)
          
            MenuItem(1, "Forward")      
            MenuItem(2, "Delete")      
          
            DisplayPopupMenu(menuRes,WindowID(w1)) 
            
            tries = 0  ;ENSURE THAT WE RETURN TO OUTER EVENT LOOP
            
            Repeat
              
              Event = WaitWindowEvent()  
              EventType = EventType()
              
              Select Event 
                Case #PB_Event_Menu ; a popup-menu item was clicked

                  Select EventMenu()     ; get the clicked menu item...
  
                    Case 1 :

               id = Val(GetGadgetItemText(#Email,menuPos,0))                    
                      ForwardEmail(id)
  
                    Case 2 :

                      id = Val(GetGadgetItemText(#Email,menuPos,0) )
  
                      If DeleteEmail(id) 
                        RemoveGadgetItem(#Email,menuPos)
                      EndIf 
                      
                  EndSelect ;EventMenu()
                  
              EndSelect ;WaitWindowEvent()
              
      ;THIS IS WHAT ENSURES THAT WE RETURN TO OUTER EVENT LOOP!!

        tries + 1 
              
      Until Event = #PB_Event_Menu Or EventType = PB_EventType_LeftClick Or tries > 5

          EndIf ;menuPos > -1 and menuPos < countGadgetItems(#Email)...

        EndIf ;menuRes
This seems to be working well with the ListIcon gadget, sans side effects!

:)

Thanks again,
Roark

Posted: Mon Apr 13, 2009 12:26 pm
by srod
Well, in my opinion that is still not the way to proceed.

When a pop-up menu is displayed, Windows takes over and tracks the menu selection etc. It is not quite a modal event loop that it enters at this point, but it is very similar. The point being that your PB program is effectively halted but for any callbacks which you may have running which will continue to receive certain messages etc.

A second event-loop is thus pointless really.