The dreaded ConstructContextualMenu

I have the following code and when it fires from right click, the globals ObjectWithMouseOver = -1 and ObjectWithSelection = -1.

Why do I still get a contextual menu with a Delete menu item?

Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) As Boolean
 
  if ObjectWithMouseOver > -1 and ObjectWithSelection > -1 then
    base.Append(New MenuItem("Delete"))
  else
    return false
  end if
  
  Return True
End Function

Put a breakpoint on the if statement and check those properties. I bet they’re not what you think they are.

Breakpoint in. Context menu still popping up and execution is not stopping at the break point.

The values have been greater than -1 to initially popup the menu as it should. I then click away from one of my objects and ObjectWithMouseOver = -1 and ObjectWithSelection = -1 and I have checked this with MsgBox just above the code shown. In fact, i’ll uncomment the MsgBox code you see in the image above, see below:

Uh… Are you sure that the menu is being created here? Do you maybe have something in the MouseDown event that creates a menuitem and then shows it with the .popup method?

Nope, its the only contextual menu in the whole project. I have had similar issues before see an old post https://forum.xojo.com/8246-context-menu

I’ll see if I can recreate and drop-box it for you in a smaller projects.

Known bug. feedback 31366. The workaround is to keep a reference to the Base menu and delete the items via code if no menu is to be shown…

One can verify that indeed the old menu is shown:

Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) As Boolean If x > 100 Then base.Append(New MenuItem("x-position: " + Str(x))) Else Me.AddRow("x-position:" + Str(x)) End Return True End Function

I can’t believe this still exists on something so commonly used. And surely the internal fix is to clear base after the menu is created.

I would expect Base to be a new menuItem created when the event is raised, but I’d be wrong.
Please sign on to the bug and maybe it will get fixed soon! :wink:

Not waiting anymore, I have created a new class and put it on GitHub to do contextual menus. My class effectively resets ‘base’ after the event is raised. It has 2 methods and 1 event, real easy to use…

https://github.com/CharlieXojo/classContextualMenu

[quote=113964:@jim mckay]I would expect Base to be a new menuItem created when the event is raised, but I’d be wrong.
Please sign on to the bug and maybe it will get fixed soon! ;)[/quote]
Jim, I have signed on

Here’s a simpler way to workaround than what’s in the feedback case…

[code]Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) As Boolean

Static lastBase as MenuItem=base
while lastbase.Count>0
lastbase.Remove(0)
wend
lastBase=base

//Normal code to show the menu or not…

End Function
[/code]

As far as I can tell the rectControl class must have a contextualMenu property that gets replaced with the new base menu, but if the base has no items, the old menu is not replaced and hence, the old menu is shown again…
Try this code in a canvas…

static count as integer=1 if x<100 then base.Append new MenuItem("Click #"+str(count)) end if count=count+1 Return true

Are you saying that returning False, it still shows a menu?

huh? I’ll have to double check this as I use this in several apps and don’t ever recall seeing the wrong menu.

[quote=114032:@Greg O’Lone]Are you saying that returning False, it still shows a menu?

[/quote]
Returning true or false seems to have no impact on behavior either way…

Mike or Jim, is there a feedback case with an example that we can look at?

I believe it was fixed yesterday by joe ranieri for the next release. Case 31366