MDI menu doesn't get updated Topic is solved

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.
Post Reply
chrismcb
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Nov 02, 2007 11:58 am

MDI menu doesn't get updated

Post by chrismcb » Sun Jan 23, 2011 8:27 pm

I've got an MDI window with a toolbar.
I've got an EVT_UPDATE_UI set up. I can see the enabled and checked states work as the toolbar changes. I can also see them in my context menu.
But the main menu doesn't change.

The update event is attached to my main app frame, the same place I called SetMenuBar.

Is there something else I need to do, or can the main menu not update in MDI mode?

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2672
Joined: Sun Jan 03, 2010 5:45 pm

Post by PB » Mon Jan 24, 2011 11:13 am

IIRC from my MDI experience (I used DocView MDI though) the toolbar is owned by wxMDIParentFrame (of course MDI children can have their own toolbars, but this is very unusual, these would be placed in the MDI child window itself and not below the menu bar).
With menubars, the situation is a bit more complicated.
There can be several menubar objects:
- One that is owned by wxMDIParentFrame, ie. the same owner as the main toolbar. This one is used when there's no MDI child.
- Every wxMDIChildFrame deriveee usually creates its own menubar (that's what I did, I have no idea how it works when there's no menubar for an MDI child window).

My blind guess is that you may need to bind the UpdateUI event to a handler in your window derived from wxMDIChildFrame and not (only) to the one derived from wxMDIParentFrame, i.e. the same event handler which handles the commands themselves. If your MDI child windows don't create and set their own menubars, maybe they should, see MDI sample.

chrismcb
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Nov 02, 2007 11:58 am

Post by chrismcb » Tue Jan 25, 2011 5:40 pm

I currently only have one menubar, and that is the one associated with the MDI Frame. I am not overriding the menubar based on the child. I don't want the menu to change, and I don't see any reason to create new menubars for each child. For one thing I am not sure I want items to appear and disappear based on what child window has focus. And in addition how is the child supposed to know about global menu items that the parent is adding? And how is the child supposed to control those items?

If the global menu items attach to the child handler, do they need to do this every time the child changes?
Seems like a flaw in the design of the MDI menu if it is the case.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2672
Joined: Sun Jan 03, 2010 5:45 pm

Post by PB » Tue Jan 25, 2011 7:21 pm

I can only recommend you look into MDI sample and check wxWidgets docs. The way it is done looks natural and makes sense to me. To have different menubar when there were no children is how it used to be done even in the most mainstream applications like MS Word back when MDI was all the rage.
If you want to do it your way, I still think you need to route UpdateUI messages to the correct event handler, in your case the MDI parent. This doesn't make much sense to me though, how is the MDI parent supposed to know what commands should and should not be allowed at any given time - it's the MDI child that is actually supposed to do all the work, the parent basically just manages the windows. :S

chrismcb
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Nov 02, 2007 11:58 am

Post by chrismcb » Wed Jan 26, 2011 8:08 am

The problem is the MDI Example doesn't modify the menu bar via EVT_UPDATE_UI. As far as I can tell this is what the wxWidget docs tell me to do, if I want to change the menu items (disabled or checked)

Right now the UpdateUI messages ARE getting to the parent. That isn't the problem. As I pointed out before everything works correctly for the Toolbar (that is also owned by the parent)

I have a Menu that has global items, and some "local" items. The way I envision this working is messages are sent to the active child (seems to happen) The active child reports on the menu items it knows about. For menu items it doesn't know about, the message is forwarded to the Main App frame. Again this seems to work.

Messages appear to be passed around correctly, as I can see items on my toolbar items being checked and disabled. But the menubar isn't updated.

The menubar doesn't update even when I have no child windows.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2672
Joined: Sun Jan 03, 2010 5:45 pm

Post by PB » Wed Jan 26, 2011 9:16 am

chrismcb wrote:The problem is the MDI Example doesn't modify the menu bar via EVT_UPDATE_UI.
Actually, the MDI sample (which uses different menubars for the parent and child frames) does disable/enable a menu item - "Child/Copy text from Clipboard".
MDI Sample (trunk) wrote:

Code: Select all

BEGIN_EVENT_TABLE(MyChild, wxMDIChildFrame)
...
    EVT_UPDATE_UI(wxID_PASTE, MyChild::OnUpdatePaste)
...
In the sample the toolbar item for this command is not updated because:
1. The toolbar item is not added with wxID_PASTE and
2. MDI parent frame doesn't handle updateUI for wxID_PASTE


The only thing that comes to my mind that you either:
* Have managed to have different IDs for menu and toolbar Rather unlikely, but still check it.
* More likely, only updateUI event for the toolbar is routed to the parent, the one for menu still goes to the child even if it doesn't have its own menubar. Try to handle the updateUI event in the child and see if it works or not.

If possible, post a minimal compilable example.

chrismcb
Knows some wx things
Knows some wx things
Posts: 26
Joined: Fri Nov 02, 2007 11:58 am

Post by chrismcb » Wed Jan 26, 2011 12:11 pm

Thanks for the help.
I completely missed that Update Event in the MDI sample.

Turns out I had my own OnMenuOpen event and I wasn't skipping the event. So I was essentially swallowing the event and not giving the system an opportunity to update the menus.

Post Reply