In our program, we want replace item menu in real time, but when we do it the menu are shuffled.
Here a program that re-create the problem.
Code: Select all | Expand
#include <FiveWin.ch>
memvar oWithSub
proc main()
LOCAL oWnd
DEFINE WINDOW oWnd TITLE "TestMenu" MENU BuildMenu()
@ 1,1 BUTTON "Replace menu 2" ACTION ReplaceMenu(oWithSub:bAction) SIZE 100,16
@ 3,1 BUTTON "Replace menu 3" ACTION ReplaceMenu(oWithSub2:bAction) SIZE 100,16
ACTIVATE WINDOW oWnd
function BuildMenu()
local oMenu
public oWithSub, oWithSub2
MENU oMenu
MENUITEM "&Test"
MENU
MENUITEM "&First" MESSAGE "First option"
MENUITEM oWithSub PROMPT "&Second" MESSAGE "Second option"
MENU
ENDMENU
MENUITEM oWithSub2 PROMPT "&Third" MESSAGE "Third option"
MENU
ENDMENU
ENDMENU
ENDMENU
//? "init before add sub",tmenuItem():nInitId
ReplaceMenu(oWithSub:bAction)
ReplaceMenu(oWithSub2:bAction)
return oMenu
#define MF_BITMAP 4
#define MF_POPUP 16 // 0x0010
proc ReplaceMenu(oMenu)
local i
LOCAL cTxt, oItem
static nTime := 0
//? "Replace 1",tmenuItem():nInitId
for i:=len(oMenu:aMenuItems) to 1 step -1
oMenu:DelItem(i)
next
oMenu:aMenuItems := {}
//? "Replace 2",tmenuItem():nInitId
nTime+=1
cTxt := alltrim(str(nTime)) + " times"
oItem := TMenuItem():New("Sub 1 Replaced " + cTxt)
oItem:bAction := {|i| MsgInfo(i:cPrompt) }
//? oItem:cPrompt, oItem:nId
oMenu:Add(oItem)
oItem := TMenuItem():New("Sub 2 Replaced " + cTxt)
oItem:bAction := {|i| MsgInfo(i:cPrompt) }
//? oItem:cPrompt, oItem:nId
oMenu:Add(oItem)
//? "Replace 3",tmenuItem():nInitId
return
If after the first run we click on "Replace menu 2" the thrid menu sub item execute the the code block of the second...

Sorry, the gif is not very clear
In our main program the prompt are shuffled too.