Menu UpdateUI events

Hi all,

I'm trying to override the default context menu for a wxTextCtrl.
I can create and display the menu, but I can't seem to override
the default "update UI" routines. MY menu is drawn, but since
I'm using the Ids wxID_UNDO, wxID_CUT, etc. in my replacement
menu, the base control seems to be enabling/disabling my menu's
entries!

The wxMenu example is pretty thin when it comes to menu UpdateUI
activities...

The wxWindows doc says that you use:
  EVT_UPDATE_UI(id, func)
  Process a wxEVT_UPDATE_UI event for the command with the given id.

And yet, the wxMenu demo uses:
  EVT_UPDATE_UI(wxGetApp(), 506, self.TestUpdateUI)

Why the wxGetApp()? How is this bound to the menu?

I've been reading the wxWindows doc, and it says:

The doc also says:
  wxMenu::UpdateUI
  void UpdateUI(wxEvtHandler* source = NULL) const

  Sends events to source (or owning window if NULL) to update
  the menu UI. This is called just before the menu is popped
  up with wxWindow::PopupMenu, but the application may call
  it at other times if required.

But there are absolutely no examples of this being used/defined
in a derived wxMenu class in the demo.

I've tried a lot of variations on the wxMenu example, but
as yet I've been unsuccessful in either getting my own handler
to fire or get the base control to stop its default behavior.

So here's what I want to do: use EVT_RIGHT_UP to bring up
my own menu, but hook in to the update UI chain to a) do my
own enabling/disabling of the menu items, and b) suppress
the default "update ui" behavior of the base control.

Can someone enlighten me on how to do this?

Thanks in advance,
/Will Sadkin
Parlance Corporation
www.nameconnector.com

Will Sadkin wrote:

Hi all,

I'm trying to override the default context menu for a wxTextCtrl.
I can create and display the menu, but I can't seem to override the default "update UI" routines. MY menu is drawn, but since I'm using the Ids wxID_UNDO, wxID_CUT, etc. in my replacement menu, the base control seems to be enabling/disabling my menu's entries!

The wxMenu example is pretty thin when it comes to menu UpdateUI
activities...

The wxWindows doc says that you use:
  EVT_UPDATE_UI(id, func) Process a wxEVT_UPDATE_UI event for the command with the given id.

And yet, the wxMenu demo uses:
  EVT_UPDATE_UI(wxGetApp(), 506, self.TestUpdateUI)

Why the wxGetApp()?

I don't know why it is there, (I didn't write it.) All events that are not handled are sent also to the app object as a last resort, so the above is legal.

How is this bound to the menu?

Update UI events are not really bound to the menu anyway, but (conceptually) to command IDs. It allows you to enable/disable/etc. all menu items/toolbar items/etc. with the same ID simply by calling methods of the event object. The code that sends the event will do the rest of the work for you.

I think the event is supposed to be sent first to the window that owns the menu or menubar/toolbar, so normally it would be the frame or the self that does self.PopupMenu, but there may still be some slight differences between platforms. Since wxUpdateUIEvent is a command event it will go up the parent window chain looking for a handler.

I've been reading the wxWindows doc, and it says:

The doc also says:
  wxMenu::UpdateUI
  void UpdateUI(wxEvtHandler* source = NULL) const

  Sends events to source (or owning window if NULL) to update the menu UI. This is called just before the menu is popped up with wxWindow::PopupMenu, but the application may call it at other times if required.

But there are absolutely no examples of this being used/defined
in a derived wxMenu class in the demo.

You shouldn't need to use it, and you shouldn't normally need to derive from wxMenu either.

I've tried a lot of variations on the wxMenu example, but as yet I've been unsuccessful in either getting my own handler to fire or get the base control to stop its default behavior.

So here's what I want to do: use EVT_RIGHT_UP to bring up
my own menu, but hook in to the update UI chain to a) do my
own enabling/disabling of the menu items, and b) suppress the default "update ui" behavior of the base control.

Can someone enlighten me on how to do this?

Attach the EVT_UPDATE_UI handlers to the textctrl and don't call event.Skip() in the handlers.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!