Adding to the OS Supplied Contextual Menu

OK, I have a listBox and added the constructContextualMenu event handler and ContextualMenuAction event handler.
I was even happy to learn that I can use MenuHandlers on the window to catch and handle the ContextualMenu actions!
All works great BUT now I then noticed that the OS supplied contextual menu items (Cut/Copy/Paste and others) are missing.
Is there a way to get the OS supplied contextual menu, then add my items to that?

What OS ?

On El Capitan / Xojo 2019r1.1: the OS supplied ContextualMenus are included !

Confirmed:
Brand new project (El Capitan / Xojo 2019r1.1),
Set the Cell to Editable,
Add a Cell in Open Event,
Click in the Row to Edit the Cell contents,
Right-Click display the ContextualMenu WITH the macOS provided items.

The TextField to edit the text has a contextual menu, but the Listbox itself has no default contextual menu.
But you can make one of course.

I forgot to mention to add the Events and the code as said in the LR for Listbox. I really neded my afternoon nap.

You do not even have to type a code for the testings.

David ?

[quote=442207:@David Adams]OK, I have a listBox and added the constructContextualMenu event handler and ContextualMenuAction event handler.
I was even happy to learn that I can use MenuHandlers on the window to catch and handle the ContextualMenu actions!
All works great BUT now I then noticed that the OS supplied contextual menu items (Cut/Copy/Paste and others) are missing.
Is there a way to get the OS supplied contextual menu, then add my items to that?[/quote]
You could always add them yourself.

Here is how you add to your listbox the edit menu, and your own options :

Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) Handles ConstructContextualMenu as Boolean for i as integer = 0 to EditMenu.count-1 base.append(EditMenu.Item(i)) next base.Append(New MenuItem("This is my menuItem")) End Function

Function ContextualMenuAction(hitItem as MenuItem) Handles ContextualMenuAction as Boolean if hitItem.Text = "This is my menuItem" then MsgBox("This is my menuItem") End Function

Note you have nothing to add in ContextualMenuAction for the built in functions. It is all automatic.
Only for your own addition

I appreciate everyone’s input, but I haven’t really found any real solution. Let me explain.
My app (MacOS Mojave & Windows 10) has list boxes, textEdits and combo boxes among other controls.
If I do nothing and use the generic controls, right-click on edit box gives a fairly full (on mac) contextual menu (Cut/Copy/Paste and Spelling and Grammar, Substitutions, Speech sub-menus).

If I add
base.append(new MenuItem(“TEST”))
to the ConstructContextualMenu() even handler for one of the textEdit controls, the resulting menu has only 1 item, ‘TEST’ It doesn’t matter whether I return True or False in the ConstructContextualMenu() event handler.

I know that I can add (in constructContextualMenu()) the Cut, Copy & Paste, but how can I get the other entries into the contextual menu that the OS supplied before I added the ConstructContextualMenu() event handler.

I hope that makes my question much more clear.


base.Append EditCut.Clone
base.Append EditCopy.Clone
base.Append EditPaste.Clone
base.Append EditClear.Clone
base.Append new MenuItem("-")
base.Append EditSelectAll.Clone

@Dave S: that’s just a workaround for the most common ones.
@David Adams and others would like to know how to get the “system provided ones”, and add own ones to those.
So how about all those other/dynamic ones, such as for SpellChecking and other system provided ones? They seem to get “lost” when implementing ConstructContextualMenu

On macOS ?
Apple really hacked that to get those into the main application menu bar to be honest

As far as I recall they actually add them after the app has done whatever it needs to with the menu bars to enable / disable so they didnt actually exist in a context that you could tell they were present (since they got added AFTER the enable menu item event has completed)
Its why changing the name of the Edit menu from “Edit” to "Edit " has almost no visual impact but makes it so the system cannot locate the right menu to insert those items into the end of. The AppKit code literally finds the menu by name and if its not matched exactly it does nothing.

[quote=442840:@David Adams]If I add
base.append(new MenuItem(“TEST”))
to the ConstructContextualMenu() even handl[/quote]

Apparently, you have not even read the post just before yours :confused:

I have… but that code will give you a MenuHasParentException. One would at least need to .Clone the already existing MenuItems: base.append(EditMenu.Item(i).Clone)
And… it obviously only gives the ones we have in the EditMenu. I don’t get the SpellChecking ones (which will appear if I don’t implement the ConstructContextualMenu.

you need to use .CLONE or they won’t work

@Jürg Otter
not sure you could call .clone on the system added ones since they arent xojo menu items

you could disable them app wide
see https://stackoverflow.com/questions/21369736/remove-start-dictation-and-special-characters-from-menu/30046514

by writing to the user prefs for the app early on

and you may be able to use declares to get to them and then handle them as NSMenuItems (see the last comment using Swift 4 and Xcode 9.2)
It requires you to access them through the shared menu bar instance

Dave, I am sorry, but I tested before posting, and it works flawlessly, at least on Mac.

It shouldnt since a menu item cant exist in 2 menu’s at the same time
You should get an exception in more recent versions

UNLESS you’re using an old version ?

You are right, Norman. In 2019R1.1, I get an error.

Sorry, Dave, I doubted you.

Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) Handles ConstructContextualMenu as Boolean for i as integer = 0 to EditMenu.count-1 base.append(EditMenu.Item(i).Clone) next base.Append(New MenuItem("This is my menuItem")) End Function

Function ContextualMenuAction(hitItem as MenuItem) Handles ContextualMenuAction as Boolean if hitItem.Text = "This is my menuItem" then MsgBox("This is my menuItem") End Function

A little bit of a clue.
I had created a contextual menu with these entries: (3 + a divider)
Paste

Conceal Search Bar
Tint Window Header >

That menu was NOT modified by the OS when I right-clicked on a combo box

However, when the menu I built was:
Cut
Copy
Paste
Clear

Conceal Search Bar
Tint Window Header >

Now a right-click on the same combo box gives the expected menu, PLUS one new entry added to the end:
Services >

I’m going to experiment with this, and try some different control types to see the results.
I’ll report back.

[quote=442914:@Michel Bujardet]You are right, Norman. In 2019R1.1, I get an error.

Sorry, Dave, I doubted you.[/quote]

No worries :slight_smile:

It was Norman that told me about the use of .Clone, as I needed to cirvumvent this exact error, way back in 2016r4