I suddenly have a need for my app to destroy and recreate a menu during runtime. Until now, I do this at the start and check that non-zero is returned for success, and I give a warning and quit the app if 0 is returned for failure.
However, since 0 is returned if the menu wasn't created successfully, what are the real-life odds that this will return 0 sometime during runtime if I destroy and recreate this menu over and over? Because if it does, then my app will be unusable.
Destroying/recreating menus at runtime
Re: Destroying/recreating menus at runtime
If I understand your question correctly, I believe you could just check the menu is valid with IsMenu().
Re: Destroying/recreating menus at runtime
why you need to destroy it? cant you just hide it?
c ya,
nco2k
c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
Re: Destroying/recreating menus at runtime
The top X items of the menu are set at runtime, every 10 minutes, with the number of X items unknown (can be 0 or up to 50). The bottom 3 items are always the same. So depending on how many items the user has, I need to put them at the top of the menu. There's no way to do that without creating it from scratch, is there?
[Edit] To explain numbers of menu items can also be 0.
[Edit] To explain numbers of menu items can also be 0.
Last edited by Dude on Sun Jul 31, 2016 5:02 am, edited 1 time in total.
Re: Destroying/recreating menus at runtime
well, you can use winapi to remove just the items and recreate them again. i dont see a reason why you should free the entire menu. but thats just me. either way, it wont fail. chances are as slim as with OpenWindow().
edit: if you are using timers, just make sure that you dont change anything while the user is currently working with the menu.
c ya,
nco2k
edit: if you are using timers, just make sure that you dont change anything while the user is currently working with the menu.
c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
Re: Destroying/recreating menus at runtime
I guess I could remove the existing items (since I have their handles), but I also have a MenuBar() between those and the permanent 3 menu items at the bottom, and I don't want that MenuBar() there if 0 items are added. However, there's no handle for MenuBar() so I don't know how I'd remove that item. (Partly the reason why I was recreating the menu from scratch).
Re: Destroying/recreating menus at runtime
In my stuff I always recreating menus from scratch, destroying previous menu (referenced by PB number) before that.
It looks like following
On windows menus are locking program execution while they displayed, so generally you cannot change items of menu which is currently shown. So it is better to recreate it anyway, rather than editing existing menu.
Anyway I found too complicated to work with menu item handles separately (doing this only in special cases, for example one my program appends popup menus of its plugins to own popup menu, that's where using handles is OK)
It looks like following
Code: Select all
; some procedure like ShowMenu()
If IsMenu(#MAIN__MENU) : FreeMenu(#MAIN__MENU) : EndIf
Protected *hMnu = CreatePopupMenuEx(#MAIN__MENU, @MNU_callback())
If *hMnu
; then code is adding menu items and displays it
EndIf
Anyway I found too complicated to work with menu item handles separately (doing this only in special cases, for example one my program appends popup menus of its plugins to own popup menu, that's where using handles is OK)
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Re: Destroying/recreating menus at runtime
yes, unfortunately pb doesnt return the handle. if you know the position of the seperator, you could use api to free it. its a shame that pb still lacks the proper functions and flexibility to do serious work with menues.Dude wrote:I guess I could remove the existing items (since I have their handles), but I also have a MenuBar() between those and the permanent 3 menu items at the bottom, and I don't want that MenuBar() there if 0 items are added. However, there's no handle for MenuBar() so I don't know how I'd remove that item. (Partly the reason why I was recreating the menu from scratch).
c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
Re: Destroying/recreating menus at runtime
The separator (MenuBar) will always be at the same position, so I'll look into how to remove a menu item by position. Should be easy. Thanks!nco2k wrote:if you know the position of the seperator, you could use api to free it.
Re: Destroying/recreating menus at runtime
Dude wrote:The separator (MenuBar) will always be at the same position, so I'll look into how to remove a menu item by position. Should be easy. Thanks!nco2k wrote:if you know the position of the seperator, you could use api to free it.
Here is some example function of whole popup menu traversing. I've took it from one my app so it is not pretty clear but shows how to access menu items by their index and menu main handle. It is possible to change item params this way, using SetMenuItemInfo(), but for deletion should use something else.
For me It looks really clearer to just recreate whole menu every time, than messing with single items through APIs, but good luck if you going to try ^^
Code: Select all
EnableExplicit
; nItem is item position (starts from 0)
Procedure FakeDLLMenuIDs (hMenu, nItem = 0)
Protected TMP.MENUITEMINFO
TMP\cbSize = SizeOf(MENUITEMINFO)
TMP\fMask = #MIIM_ID | #MIIM_SUBMENU | #MIIM_STRING ; flags of query using GetMenuItemInfo
If GetMenuItemInfo_(hMenu, hItem, #True, @TMP)
If TMP\hSubMenu ; one more submenu
FakeDLLMenuIDs(TMP\hSubMenu, 0)
Else
; TMP\fMask = #MIIM_ID
; TMP\wID = StartFakeIndex + TMP\wID ; replace original wID to our internal
; SetMenuItemInfo_(hMenu, nItem, #True, @TMP)
Debug TMP\wID ; all menu separators having wID -1.
Debug "------"
EndIf
FakeDLLMenuIDs(hMenu, nItem + 1)
EndIf
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;
Define A = CreatePopupMenu(#PB_Any)
MenuItem(5, "test")
MenuBar()
MenuBar()
MenuItem(6, "test2")
FakeDLLMenuIDs(MenuID(A), 0)"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"

