Advise: Best handle wxMenu/accelerator event?
Advise: Best handle wxMenu/accelerator event?
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.
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.
Re: Advise: Best handle wxMenu/accelerator event?
Hi,
Did you look at the menu sample?
Thank you.
Did you look at the menu sample?
Thank you.
Re: Advise: Best handle wxMenu/accelerator event?
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.
Re: Advise: Best handle wxMenu/accelerator event?
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!
Re: Advise: Best handle wxMenu/accelerator event?
Weird, I was reading something that suggested that works right before I created this topic, but I can't find it now???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.
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.
Re: Advise: Best handle wxMenu/accelerator event?
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.
But you can always subclass wxMenuItem and put any data you like into it.
Use the source, Luke!
Re: Advise: Best handle wxMenu/accelerator event?
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.
Re: Advise: Best handle wxMenu/accelerator event?
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.
For now I'm under the impression I'm going to have to resort to a two-way lookup workaround for menu bars.
Re: Advise: Best handle wxMenu/accelerator event?
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.
I can't think of any way to identify a menu entry without a unique ID.
Use the source, Luke!
Re: Advise: Best handle wxMenu/accelerator event?
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.
Re: Advise: Best handle wxMenu/accelerator event?
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.
Just make sure IDs are unique and make your life a lot easier.
Use the source, Luke!
Re: Advise: Best handle wxMenu/accelerator event?
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.
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.
Re: Advise: Best handle wxMenu/accelerator event?
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.)
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);
Re: Advise: Best handle wxMenu/accelerator event?
No need to assume, just look at the doc:I assume if a range of IDs is not provided, then the full range applies.
Code: Select all
void wxEvtHandler::Bind(const EventTag & eventType,
Functor functor,
int id = wxID_ANY,
int lastId = wxID_ANY,
wxObject * userData = NULL
)
Shouldn't that be:fr->Bind(wxEVT_COMMAND_MENU_SELECTED,evt_command);
fr->Bind(wxEVT_COMMAND_MENU_SELECTED, &evt_command);
Re: Advise: Best handle wxMenu/accelerator event?
Hi,
Or more precisely,
where this is an eventSink parameter (and very important one).
Thank you.
Or more precisely,
Code: Select all
fr->Bind(wxEVT_COMMAND_MENU_SELECTED, &<ClassName>::evt_command, this);
Thank you.