Advise: Best handle wxMenu/accelerator event?

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Mon Jul 29, 2019 1:41 pm

I find the documentation for handling menu selection (i.e. WM_COMMAND for WSM) opaque. For context menu it's very simple. For wxMenuBar I'm unclear what to do exactly.

From the wxMenu documentation, I think it's possible to bind an event to the menu object itself? I'm not sure which flavor of event I want, since wxEVT_MENU seems to be for everything EXCEPT selection/dispatch, and the wxEVT_COMMAND looks generic.

I need to know what is the wxMenu that the even belongs to. The ID by itself is not enough in my software. In that case, if the menu is responsible for the event, then I suppose that would work.

I think there is a simple answer, but I feel like just asking is the smartest thing I can do in this case. Of course, I need a portable solution. Thanks.

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3409
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Advise: Best handle wxMenu/accelerator event?

Post by ONEEYEMAN » Mon Jul 29, 2019 3:13 pm

Hi,
Did you look at the menu sample?

Thank you.

Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Mon Jul 29, 2019 3:47 pm

ONEEYEMAN wrote:
Mon Jul 29, 2019 3:13 pm
Hi,
Did you look at the menu sample?

Thank you.
No, just documentation.

FWIW those examples are too inaccessible... by which I mean they don't turn up in web searches, so even if you stumble across them, it's a bit of effort to stash the URL away. Even having seen them before, I wouldn't know where to look to find them right now. I'm just saying, probably it would be a good idea to stash links in the (class) documentation, since those have relevant search terms (class names) that search engines can use.
Last edited by Mick P. on Mon Jul 29, 2019 3:48 pm, edited 1 time in total.

User avatar
doublemax
Moderator
Moderator
Posts: 13992
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Advise: Best handle wxMenu/accelerator event?

Post by doublemax » Mon Jul 29, 2019 3:48 pm

Almost any sample, including the "minimal" sample, shows how to handle menu events. If you want to use Bind() instead of a static event table, bind to the frame. Binding to the wxMenuBar or individual wxMenu items will not work - even if the API allows it and it would compile.
Use the source, Luke!

Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Mon Jul 29, 2019 4:03 pm

doublemax wrote:
Mon Jul 29, 2019 3:48 pm
Any sample, including the "minimal" sample, shows how to handle menu events. If you want to use Bind() instead of a static event table, bind to the frame. Binding to the wxMenuBar or individual wxMenu items will not work - even if the API allows it and it would compile.
Weird, I was reading something that suggested that works right before I created this topic, but I can't find it now???

I'm worried I'm in trouble here, like will need a roundabout solution. In this case, the next easiest approach is to associate some metadata with the menu items, but I have a feeling the event structures have no such luxury. Any ideas?

Barring that, I wonder if there is a lower-level point to tie into with a "virtual" method override somewhere in the event processing system? Sorry to be a burden.

(EDITED: For the record, if there is no other way, I can fallback to a lookup table instead of constant IDs. But for the context-menus everything is simple. The problem with menu-bars is there's no trace back to the owning menu.)
Last edited by Mick P. on Mon Jul 29, 2019 4:13 pm, edited 1 time in total.

User avatar
doublemax
Moderator
Moderator
Posts: 13992
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Advise: Best handle wxMenu/accelerator event?

Post by doublemax » Mon Jul 29, 2019 4:11 pm

Can you explain what you're trying to achieve? Binding user-data to a menu entry in the menubar would be every unusual. IMHO this only makes sense with popup menus.

But you can always subclass wxMenuItem and put any data you like into it.
Use the source, Luke!

Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Mon Jul 29, 2019 4:16 pm

doublemax wrote:
Mon Jul 29, 2019 4:11 pm
Can you explain what you're trying to achieve? Binding user-data to a menu entry in the menubar would be every unusual. IMHO this only makes sense with popup menus.

But you can always subclass wxMenuItem and put any data you like into it.
That will work. Is the wxMenuItem object part of the event structure?

(What I'm trying to achieve is a layer that hosts features like this on behalf of user-code. It can't guarantee that IDs are unique. So it can't extract a menu from an ID alone. It needs to have the menu/submenu to respond correctly to the consuming code.)

EDITED: If I can get the wxMenuItem from the event, then it's trivial to get the wxMenu from the item I think. I'm assuming if that's the case then the object pointer in the event can be cast to wxMenuItem? Or is the object the window/event-handler receiving the event? Sorry.

EDITED: For the record, viewtopic.php?t=31451 is a likely duplicate of this question.

Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Mon Jul 29, 2019 5:14 pm

FWIW I looked at the problem for Win32 and learned about a new (to me) WM_MENUCOMMAND message, that provides the handle to the menu, unlike WM_COMMAND. I guess at some point I will have to set up a trace to see what wxWidgets does. Right now I can't do that easily. It just occurred to today that getting the menus back from the commands might not be as simple as building the menu bar! (I don't know if WM_MENUCOMMAND works with accelerators... assume it does... but it seems to require enabling a MNS_NOTIFYBYPOS status.)

For now I'm under the impression I'm going to have to resort to a two-way lookup workaround for menu bars.

User avatar
doublemax
Moderator
Moderator
Posts: 13992
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Advise: Best handle wxMenu/accelerator event?

Post by doublemax » Mon Jul 29, 2019 6:32 pm

A quick textsearch over the wx sources shows that WM_MENUCOMMAND is not used anywhere.

I can't think of any way to identify a menu entry without a unique ID.
Use the source, Luke!

Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Tue Jul 30, 2019 11:48 am

Thanks for support as always! I wonder if it's possible to implement this on wxWidget's platforms. I may take it to the tracker, to see if anyone is interested in researching the possibilities. Working with `int` is not much to go on. It runs counter to most of wxWidget's design. Even if the fix is complicated, it might be something better implemented internally.

User avatar
doublemax
Moderator
Moderator
Posts: 13992
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Advise: Best handle wxMenu/accelerator event?

Post by doublemax » Tue Jul 30, 2019 3:42 pm

I don't think there is a solution for this, at least not under Windows. When you look at the documentation for WM_COMMAND, the only information that is sent with that message is a (16 bit!) ID of the menu. If that ID is not unique, there is nothing you can do to distinguish between different menu entries.

Just make sure IDs are unique and make your life a lot easier.
Use the source, Luke!

Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Thu Aug 01, 2019 11:02 pm

I don't know enough about wxWidgets to comment, but the ACCEL structure is limited to 16-bit also, even though WM_MENUCOMMAND appears to use 32-bit.

Even being limited to 16-bit unique IDs is not so bad. Probably wxWidgets could implement hotkeys without ACCEL since it isn't a cosmetic/look-feel thing.

wxWidgets generates IDs for timers (MSW) just by incrementing a static variable. I think generating native IDs for menus and mapping those to user IDs would not be so bad. It would save developers from being limited, and reimplementing the same workaround, and make wxWidgets feel more liberating. Instead of finding the minimum overlapping functionality, it can expand on functionality too.

Mick P.
Earned some good credits
Earned some good credits
Posts: 110
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: Advise: Best handle wxMenu/accelerator event?

Post by Mick P. » Sat Aug 31, 2019 5:31 pm

Bummer,

I sat down to implement this now, and finished, my wxFrame doesn't receive the events. I mean this is completely off-topic, but I feel like better to revive this topic than make anew.

For the record, the handlers are added to the frame like everything else. The procedure is not called, even while the frame has a working menu and toolbar. I think there is a technical reason or another that is mysterious. (I assume if a range of IDs is not provided, then the full range applies.)

Code: Select all

			fr->Bind(wxEVT_COMMAND_MENU_SELECTED,evt_command);
			fr->Bind(wxEVT_COMMAND_TOOL_CLICKED,evt_command);

DavidHart
Site Admin
Site Admin
Posts: 3881
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Re: Advise: Best handle wxMenu/accelerator event?

Post by DavidHart » Sat Aug 31, 2019 6:43 pm

I assume if a range of IDs is not provided, then the full range applies.
No need to assume, just look at the doc:

Code: Select all

void wxEvtHandler::Bind(const EventTag &  	eventType,
		Functor  functor,
		int  	id = wxID_ANY,
		int  	lastId = wxID_ANY,
		wxObject *  userData = NULL 
	) 		
fr->Bind(wxEVT_COMMAND_MENU_SELECTED,evt_command);
Shouldn't that be:
fr->Bind(wxEVT_COMMAND_MENU_SELECTED, &evt_command);

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3409
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Advise: Best handle wxMenu/accelerator event?

Post by ONEEYEMAN » Sat Aug 31, 2019 10:37 pm

Hi,
Or more precisely,

Code: Select all

fr->Bind(wxEVT_COMMAND_MENU_SELECTED, &<ClassName>::evt_command, this);
where this is an eventSink parameter (and very important one).

Thank you.

Post Reply