Modifying a menuItem while the menu is open

I’d like to change the name (and function) of a MenuBar menuItem by pressing the Option key while the menu is open. A declare solution is offered in this thread

The declare wouldn’t compile as-is (that thread is old), but this does

Declare Sub setAlternate Lib "AppKit" Selector "setAlternate:" (NSMenuItem As Ptr, value As Boolean)
Dim p As Ptr = myMenu2.Handle()
setAlternate(p, True)

I’ve created two identical menus right next to each other, and placed the declare in the App.opening event, which was the advice in that thread. When I run the app, both menus appear in the menubar. Since I’m not clear on what the declare does (for example, how does myMenu2 know it’s the alternate to myMenu1?), I’d appreciated thoughts on what I’m not doing correctly. Also, when polling for the OptionKey.down event in a timer, how does one actually invoke the alternate menu when it is pressed

No need for declares.

I use a timer that checks to see if modifier keys are pressed. If any of those keys are pressed then change the text of the MenuHandler for the menubar item.

In the MenuHandlers section, I check to see what the name of the menuhandler is for that menubar item, and have it execute code based on the name it has.

Sample Project here: Modifier Keys and MenuBar item text

Menubar item changing on the fly

1 Like

The declare is the system provided correct way to do this… just… so you know.

1 Like

@Tim_Parnell Mark’s sample project still works, and without declares…
I think it’s because it uses desktopmenus
I recall it didn’t work with former menus years ago when I tried it.

I did not say it failed to operate. I did not say the declare was going to work on Windows, or that it would be a great cross platform solution. All I said was there is a correct, Apple provided way to do this on macOS (the subcategory where this thread is located).

This should not be a goal when trying to achieve something the Xojo Framework does not directly allow.

The alternate item declare works great when you follow Eli Ott’s instructions and know how to update declares for API 2.0. There’s also no lag to the functionality, as I suspect you will find with a Timer.


Here is that in a working project:

1 Like

My project is huge and uses API1, so no DesktopMenus. Thank you @Mark_Sweeney and @Tim_Parnell for the advice and projects. I’ll adapt Tim’s, it looks like it’s exactly what I need.

You shouldn’t have had to update anything in the declare for API 1. What was the compiler complaining about?

If you get stuck, I’ve adjusted the example for API 1 / MenuItem:

You do actually. handles were Integers in API 1 and are Ptrs now, so that first parameter in the declare needs to be changed to an Integer.

I am aware, but the original post (edit: I mean the 2017 post) was written in API 1 and does work out of the box. I was hoping to help figure out why it seemed to need adjustments.

It didn’t like

Dim p As Ptr = Ptr(UntitledItem0.Handle(MenuItem.HandleType.CocoaNSMenuItem))

“There is more than one method with this name but this does not match any of the available signatures”

I saw that error during conversion because DesktopMenuItem.Handle and MenuItem.Handle accept different parameters. I might suggest double checking you were working with MenuItem and not a DesktopMenuItem.

I created a new project specifically for testing the menu code using Xojo2023r1.1, so it is a DesktopMenuItem. I figured it might be an API1 vs API2 thing, I’m not that conversant in API2. My real app will use the API1 code. Thanks.

That would explain it :slight_smile:

If you’re going to be working in API 1 for a while, I might suggest that you create an API 1 project template so that you can test things with API 1 controls. Using an older IDE, save a project named Default Desktop Project.xojo_binary_project in a folder named Project Templates next to

1 Like