Contextual Menu

The RectControl.ConstructContextualMenu returns a Boolean.
You have to return TRUE to display the Menu, if you return FALSE the Menu should not be displayed.
That’s at least my understanding from the Language Reference.

If I take the Xojo ContextualMenu Example and change the Return Value to FALSE the Menu is still displayed.
Also in one of my Application the Menu behaves not as expected if compiled in Cocoa, in Carbon it works as it should.

Do I miss something?
Anybody else seeing this Behaviour? If yes, is there a workaround?

Regards Peter

Actually, not quite true. Like most of the event handlers, returning True indicates that the event handling is complete and no further action is to be taken for that event. Returning False indicates that the event handling will continue with the parent’s event handler.

I believe that in either case, the menu should be displayed. ( BTW, That’s the way it works in Windows also.)

As a workaround, determine the conditions for displaying the menu and wrap the code in an if…end if block based on that condition. For example, in the ConstructContextualMenu event for a listbox:

If Me.ListCount > 0 Then base.Append( New MenuItem( "Remove Item" ) ) Return True End If Return False

In layman’s terms, if you put a listbox inside a rectangle then a Contextual Click on the listbox will:

(Return False)
pass Base to the rectangle and run its ConstructContextualMenu before showing the Menu. This will give you both the Listbox’s and Rectangle’s Contextual MenuItems on 1 menu (Base).

(Return True)
NOT pass Base to the rectangle and only show the Listbox’s Contextual Menu

In Dales example if your Parent (even the window itself) is using ConstructContextualMenu then you will still get a Contextual Menu on the screen

Thank’s both of you, but I see a different Behaviour.
If you have time do the following:

Open a new Project, put a ListBox with 2 columns on the Window.
In the Open event of the Window put following code:
Listbox1.AddRow “State”, str(-1)
Listbox1.AddRow “Boston”, str(2)
Listbox1.AddRow “State”, str(-1)
Listbox1.AddRow “Atlanta”, str(3)
Listbox1.AddRow “Macon”, str(4)

In the ConstructContextualMenu event of the Listbox:
Dim row As Integer = me.RowFromXY(x,y)
if Val(me.Cell(row,1)) = -1 then
return False
base.Append( New MenuItem( “Test 1” ) )
base.Append( New MenuItem( me.Cell(row,0) ) )
return True
end if

Now run the Project.
In CARBON it behaves exactly as expected, NO ContextMenu when you click ‘State’.
In COCOA initially there is no ContextMenu when you click ‘State’, - BUT as soon as you have once clicked on a city
and then click on ‘State’ again the last ContextMenu is shown.

Could this be a Bug or do I miss something?

Why are you returning False? That passes Base to the Parent, which is probably Window1. Just don’t append anything to Base and return True. Never return False unless you want to pass Base to the Parent. Only wrap your base.append statements in the If Statement and return True

Dim m1 as New MenuItem(“Test”, Nil)

If Something = Something then
Base.Append m1
End If
Return True

It sounds like it might be a bug in the Cocoa version (I don’t have Cocoa so I can’t try it there.) It works in Windows just like your description of operation in Carbon.

Probably related:

Sounds like it’s because you are returning false and the menu item ‘base’ is being held by Window1 and your not getting a new base each time like you would if you returned True. Test it with breaks in your construct Contextual Menu events. Meaning the Listbox AND Window1

I have tested it as you suggested. Even if I return TRUE in both cases - no difference, ContextMenu still displayed
when I click ‘State’.
In Window1, ‘base’ MenuItem of ConstructContextualMenu event is empty in both cases.
(return TRUE or FALSE from Listbox ConstructContextualMenu event)

Put a breakpoint after the Else to see when ‘State’ is being added to base. Maybe RowFromXY(x, y) is the issue?

Easiest way to get rid of it would be
If me.Cell(row, 1) = “-1” then
base = New MenuItem
End if

Making base a new menuitem will destroy base and nothing will be shown.

I just ran into this same bug in 2013r4.1… Cocoa debug build. Canvas control.
Setting the menu to nil will not destroy the old menu.
Setting Base to a new MenuItem doesn’t help.
Calling Base.close doesn’t work either.
In all cases, the last shown menu is shown. The ContextualMenuAction doesn’t fire however, if the menu is the zombie…
returning true or false has no effect.
Even adding a new item to base and then removing it to empty base will cause the zombie to show…
Haven’t checked other platforms yet…