Page 1 of 1
A way to check if a menu was dismissed with no items selected
Posted: Sun Aug 18, 2024 5:41 am
by nsstudios
Hi,
It would be really useful if there was a way to catch menu dismiss event.
Maybe EventMenu could get a special negative number event if the menu got closed (with escape or otherwise), but no items were selected?
I don't know what PB uses under the hood, but (at least on Windows), by using CreatePopupMenu_(), AppendMenu_(), and TrackPopupMenuEx with #TPM_RETURNCMD, I can get 0 as return from TrackPopupMenu, and by checking GetLastError_()=0 to make sure that doesn't mean there was an error, I can be sure that no items were selected and that the menu was dismissed.
This would be really useful for triggering different conditions based on if the menu was just dismissed or an item was actually selected, which isn't currently possible without using OS-specific API's unless I'm missing something.
Re: A way to check if a menu was dismissed with no items selected
Posted: Sun Aug 18, 2024 6:39 am
by BarryG
Maybe I'm missing the point, but #PB_Event_Menu will never be triggered if a menu item isn't selected. So you don't need to do anything unless a menu item is actually selected and causes that event trigger?
Re: A way to check if a menu was dismissed with no items selected
Posted: Sun Aug 18, 2024 7:23 am
by AZJIO
Try using flags
The menu closing event arrives before the item event arrives
Code: Select all
EnableExplicit
#Window = 0
Enumeration
#Menu
#PopupMenu
EndEnumeration
Global flag
Procedure WinCallback(hWnd, Msg, wParam, lParam)
Select Msg
Case #WM_ENTERMENULOOP
flag + 1
If wParam
Debug "Context menu open"
Else
Debug "Main menu open"
EndIf
Case #WM_EXITMENULOOP
; If flag
; EndIf
flag -1
Debug flag
If wParam
Debug "Context menu closed"
Else
Debug "Main menu is closed"
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure EventsPopupMenu()
DisplayPopupMenu(#PopupMenu, WindowID(#Window))
EndProcedure
If OpenWindow(#Window, 0, 0, 320, 240, "Menu", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreateMenu(#Menu, WindowID(#Window))
MenuTitle("File")
MenuItem(1, "New")
EndIf
If CreatePopupMenu(#PopupMenu)
MenuItem(2, "Copy")
EndIf
SetWindowCallback(@WinCallback())
BindEvent(#PB_Event_RightClick, @EventsPopupMenu())
Repeat
Select WaitWindowEvent()
Case #PB_Event_Menu
Select EventMenu()
Case 1
flag + 1
Case 2
flag + 1
EndSelect
Case #PB_Event_CloseWindow
CloseWindow(0)
End
EndSelect
ForEver
EndIf
Re: A way to check if a menu was dismissed with no items selected
Posted: Sun Aug 18, 2024 11:49 am
by nsstudios
BarryG wrote: Sun Aug 18, 2024 6:39 am
Maybe I'm missing the point, but #PB_Event_Menu will never be triggered if a menu item isn't selected....
Maybe I was unclear, but that's exactly my problem. Say I wanted to play menu open and menu close sounds. I currently don't get any kind of event when a menu closes and no item was selected, so I couldn't do that.
@AZJIO Haven't thought of that. Thanks.
I currently use TrackPopupMenu_() but would be nice to have an x-platform built-in way to handle this.
Code: Select all
EnableExplicit
OpenWindow(0, #PB_Ignore, #PB_Ignore, #PB_Ignore, #PB_Ignore, "test", #PB_Window_ScreenCentered|#PB_Window_Maximize)
;Define menu=CreatePopupMenu_()
;AppendMenu_(menu, #MF_STRING, 1, "0")
;AppendMenu_(menu, #MF_STRING, 2, "1")
CreatePopupMenu(0)
MenuItem(1, "0")
MenuItem(2, "1")
#TPM_VERPOSANIMATION=$1000: #TPM_VERNEGANIMATION=$2000: #TPM_HORPOSANIMATION=$0400: #TPM_HORNEGANIMATION=$0800
Define menuAlign=Bool(GetSystemMetrics_(#SM_MENUDROPALIGNMENT))
Define aln.point\x=(menuAlign*#TPM_RIGHTALIGN)+((menuAlign!1)*#TPM_LEFTALIGN)
aln\y=(menuAlign*#TPM_HORNEGANIMATION)+((menuAlign!1)*#TPM_HORPOSANIMATION)
Define menu=MenuID(0)
Define selected=TrackPopupMenuEx_(menu, #TPM_RETURNCMD|#TPM_LEFTBUTTON|aln\x|#TPM_VCENTERALIGN|aln\y|#TPM_HORIZONTAL|#TPM_VERNEGANIMATION, 0, 0, WindowID(0), 0)
If GetLastError_()=0
PostEvent(#PB_Event_Menu, 0, (Bool(selected=0)*-1000)+(Bool(selected>0)*selected))
EndIf
Repeat
Define e=WaitWindowEvent(1)
If e=#PB_Event_Menu
Define em=EventMenu()
If em=-1000
Debug "dismissed"
ElseIf em>0
Debug "selected "+em
EndIf
EndIf
Until e=#PB_Event_CloseWindow
Re: A way to check if a menu was dismissed with no items selected
Posted: Sun Aug 18, 2024 12:50 pm
by BarryG
nsstudios wrote: Sun Aug 18, 2024 11:49 amSay I wanted to play menu open and menu close sounds. I currently don't get any kind of event when a menu closes and no item was selected, so I couldn't do that.
Well you didn't mention that specific use case in your original post, so how was I to know?

We're coders here; be specific.
AZJIO's answer is close to what you want, but it doesn't show the "Closed" message if the Esc key is hit after the menu is open.