Page 1 of 1

TMenuItem id shuffled

PostPosted: Tue Feb 20, 2018 11:54 am
by AntoninoP
Hello,
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 view
#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...

Image

Sorry, the gif is not very clear

In our main program the prompt are shuffled too.

Re: TMenuItem id shuffled

PostPosted: Tue Feb 20, 2018 2:21 pm
by cnavarro
Antonino, thanks

His example is very good and he is right
If only I wanted to change the prompt and action there are adequate methods for it and it would work correctly, but, when deleting all the items, and re-creating them, the id counter is not correct.
For now, remove or comment this line from the End method of TMenuItems and try

Code: Select all  Expand view

METHOD End() CLASS TMenuItem

   local lFont  := ::oMenu:lFont

   ::Destroy()
   If ::hBitmap != 0
      DeleteObject( ::hBitmap )
      ::hBitmap := 0
   endif
   If ::hCheck != 0
      DeleteObject( ::hCheck )
      ::hCheck := 0
   endif
   if ::hPalette != 0
      DeleteObject( ::hPalette )
      ::hPalette := 0
   endif
   //::nInitId--                               // this line
   if !Empty( ::oFont )
      ::oFont:End()
      ::oFont := nil
   endif
Return nil

 


Your sample run ok with this modification
Code: Select all  Expand view


#include "Fivewin.ch"

static oWithSub
static oWithSub2
static nTime1 := 0
static nTime2 := 0

proc main()
   
   local oWnd
   
   DEFINE WINDOW oWnd TITLE "TestMenu" MENU BuildMenu()
   
   @ 08,10 BUTTON "Replace menu 2" ACTION ReplaceMenu1( oWithSub:bAction )  SIZE 100, 20
   @ 10,10 BUTTON "Replace menu 3" ACTION ReplaceMenu2( oWithSub2:bAction ) SIZE 100, 20

   ACTIVATE WINDOW oWnd

return
   
function BuildMenu()

   local oMenu
   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
   ReplaceMenu1( oWithSub:bAction  )
   ReplaceMenu2( oWithSub2:bAction )

return oMenu

//----------------------------------------------------------------------------//

#define MF_BITMAP         4
#define MF_POPUP         16  // 0x0010

//----------------------------------------------------------------------------//

proc ReplaceMenu1( oMenu )
   
   local i
   local cTxt
   local oItem
   /*
   for i := Len( oMenu:aMenuItems ) to 1 step -1
      oMenu:DelItem( i )
   next
   oMenu:aMenuItems := {}
   */

   oMenu:DelItems()
   
   nTime1  += 1
   cTxt    := hb_Ntos( nTime1 ) + " times"

   oItem   := TMenuItem():New( "Sub 11 Replaced " + cTxt )
   oItem:bAction := { | i | MsgInfo( i:cPrompt, i:nId ) }
   oMenu:Add( oItem )

   oItem   := TMenuItem():New( "Sub 12 Replaced " + cTxt )
   oItem:bAction := { | i | MsgInfo( i:cPrompt, i:nId ) }
   oMenu:Add( oItem )

return

//----------------------------------------------------------------------------//

proc ReplaceMenu2( oMenu )

   local i
   local cTxt
   local oItem
   /*
   For i := Len( oMenu:aMenuItems ) to 1 step -1
      oMenu:DelItem( i )
   Next
   oMenu:aMenuItems := {}
   */

   oMenu:DelItems()
   
   nTime2  += 1
   cTxt    := hb_ntos( nTime2 ) + " times"
   
   oItem   := TMenuItem():New( "Sub 21 Replaced " + cTxt )
   oItem:bAction := { | i | MsgInfo( i:cPrompt, i:nId ) }
   oMenu:Add( oItem )
   
   oItem   := TMenuItem():New( "Sub 22 Replaced " + cTxt )
   oItem:bAction := {| i | MsgInfo( i:cPrompt, i:nId ) }
   oMenu:Add( oItem )

return

//----------------------------------------------------------------------------//

 

Re: TMenuItem id shuffled

PostPosted: Thu Mar 15, 2018 10:01 am
by AntoninoP
Hello,
I am using fwh 18.01 and this fix is not included...
will it included in the next releases?

Re: TMenuItem id shuffled

PostPosted: Thu Mar 15, 2018 2:43 pm
by cnavarro
AntoninoP wrote:Hello,
I am using fwh 18.01 and this fix is not included...
will it included in the next releases?


Not run OK with previous modification?

Re: TMenuItem id shuffled

PostPosted: Thu Mar 15, 2018 4:01 pm
by AntoninoP
no, it is necessary that the line
Code: Select all  Expand view
::nInitId--

in
Code: Select all  Expand view
METHOD End() CLASS TMenuItem

is commented

Re: TMenuItem id shuffled

PostPosted: Thu Mar 15, 2018 4:20 pm
by cnavarro
Comment this line is the solution ( included in 18.02 )
I have been looking at the possibility of keeping track of the empty ids to assign it to other new items, but the process penalizes the processing speed in a routine as complex as the painting of the menus (ownerdraw).
It is not necessary for the correct operation of the menus, discount the ids counter when an item is deleted.