Return correct menu pointer for wxEVT_MENU_{OPEN,CLOSE} in MDI frames.

These events are supposed to carry a pointer to the menu which was opened or
closed, but wxMenuEvent::GetMenu() always returned NULL for the menus opened
when a child MDI frame was active, as its menu bar, containing the menu, was
not searched for it.

Fix this by overriding MSWFindMenuFromHMENU() at wxMDIParentFrame level, just
as we already do for FindItemInMenuBar().

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78130 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2014-11-11 01:02:31 +00:00
parent 2054b6b35f
commit 8de1128c07
5 changed files with 79 additions and 8 deletions

View File

@ -114,6 +114,7 @@ wxMSW:
- Fix updating wxSlider background when its parent background changes.
- Implement wxListBox::EnsureVisible() (RIVDSL).
- Drastically improve efficiency of selecting all items in wxDataViewCtrl.
- Fix wxMenuEvent::GetMenu() for wxEVT_MENU_{OPEN,CLOSE} in MDI frames.
wxOSX/Cocoa:

View File

@ -103,9 +103,10 @@ public:
virtual bool MSWTranslateMessage(WXMSG* msg);
#if wxUSE_MENUS
// override wxFrameBase function to also look in the active child menu bar
// and the "Window" menu
// override the menu-relayed methods to also look in the active child menu
// bar and the "Window" menu
virtual wxMenuItem *FindItemInMenuBar(int menuId) const;
virtual wxMenu* MSWFindMenuFromHMENU(WXHMENU hMenu);
#endif // wxUSE_MENUS
protected:

View File

@ -70,6 +70,9 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
EVT_MENU(wxID_CLOSE_ALL, MyFrame::OnCloseAll)
EVT_MENU_OPEN(MyFrame::OnMenuOpen)
EVT_MENU_CLOSE(MyFrame::OnMenuClose)
EVT_CLOSE(MyFrame::OnClose)
wxEND_EVENT_TABLE()
@ -91,6 +94,9 @@ wxBEGIN_EVENT_TABLE(MyChild, wxMDIChildFrame)
EVT_SIZE(MyChild::OnSize)
EVT_MOVE(MyChild::OnMove)
EVT_MENU_OPEN(MyChild::OnMenuOpen)
EVT_MENU_CLOSE(MyChild::OnMenuClose)
EVT_CLOSE(MyChild::OnCloseWindow)
wxEND_EVENT_TABLE()
@ -132,7 +138,8 @@ bool MyApp::OnInit()
// Define my frame constructor
MyFrame::MyFrame()
: wxMDIParentFrame(NULL, wxID_ANY, "wxWidgets MDI Sample",
wxDefaultPosition, wxSize(500, 400))
wxDefaultPosition, wxSize(500, 400)),
MenuEventLogger("parent", this)
{
SetIcon(wxICON(sample));
@ -175,9 +182,13 @@ MyFrame::MyFrame()
#endif // wxUSE_STATUSBAR
m_textWindow = new wxTextCtrl(this, wxID_ANY, "A help window",
m_textWindow = new wxTextCtrl(this, wxID_ANY, "A log window\n",
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxSUNKEN_BORDER);
wxTE_MULTILINE | wxTE_READONLY);
// don't clutter the text window with time stamps
wxLog::DisableTimestamp();
delete wxLog::SetActiveTarget(new wxLogTextCtrl(m_textWindow));
#if wxUSE_TOOLBAR
CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL);
@ -203,6 +214,9 @@ MyFrame::~MyFrame()
// and disconnect it to prevent accessing already deleted m_textWindow in
// the size event handler if it's called during destruction
Disconnect(wxEVT_SIZE, wxSizeEventHandler(MyFrame::OnSize));
// also prevent its use as log target
delete wxLog::SetActiveTarget(NULL);
}
#if wxUSE_MENUS
@ -414,7 +428,8 @@ MyChild::MyChild(wxMDIParentFrame *parent)
parent,
wxID_ANY,
wxString::Format("Child %u", ++ms_numChildren)
)
),
MenuEventLogger("child", this)
{
m_canvas = new MyCanvas(this, wxPoint(0, 0), GetClientSize());

View File

@ -37,8 +37,42 @@ private:
wxDECLARE_EVENT_TABLE();
};
// Helper class logging menu open/close events.
class MenuEventLogger
{
public:
MenuEventLogger(const char* label, wxFrame* frame)
: m_label(label),
m_frame(frame)
{
}
protected:
void LogMenuOpenClose(wxMenuEvent& event, const char *action)
{
event.Skip();
wxString what;
wxMenu* const menu = event.GetMenu();
if ( menu )
what.Printf("Menu with title \"%s\"", menu->GetTitle());
else
what = "Unknown menu";
wxLogMessage(m_frame, "%s was %s in the %s frame",
what, action, m_label);
}
const wxString m_label;
wxFrame* const m_frame;
wxDECLARE_NO_COPY_CLASS(MenuEventLogger);
};
// Define a new frame
class MyFrame : public wxMDIParentFrame
class MyFrame : public wxMDIParentFrame,
private MenuEventLogger
{
public:
MyFrame();
@ -56,6 +90,9 @@ private:
void OnQuit(wxCommandEvent& event);
void OnCloseAll(wxCommandEvent& event);
void OnMenuOpen(wxMenuEvent& event) { LogMenuOpenClose(event, "opened"); }
void OnMenuClose(wxMenuEvent& event) { LogMenuOpenClose(event, "closed"); }
void OnClose(wxCloseEvent& event);
wxTextCtrl *m_textWindow;
@ -63,7 +100,8 @@ private:
wxDECLARE_EVENT_TABLE();
};
class MyChild : public wxMDIChildFrame
class MyChild : public wxMDIChildFrame,
private MenuEventLogger
{
public:
MyChild(wxMDIParentFrame *parent);
@ -82,6 +120,8 @@ private:
void OnClose(wxCommandEvent& event);
void OnSize(wxSizeEvent& event);
void OnMove(wxMoveEvent& event);
void OnMenuOpen(wxMenuEvent& event) { LogMenuOpenClose(event, "opened"); }
void OnMenuClose(wxMenuEvent& event) { LogMenuOpenClose(event, "closed"); }
void OnCloseWindow(wxCloseEvent& event);
#if wxUSE_CLIPBOARD

View File

@ -447,6 +447,20 @@ wxMenuItem *wxMDIParentFrame::FindItemInMenuBar(int menuId) const
return item;
}
wxMenu* wxMDIParentFrame::MSWFindMenuFromHMENU(WXHMENU hMenu)
{
wxMenu* menu = GetActiveChild()
? GetActiveChild()->MSWFindMenuFromHMENU(hMenu)
: NULL;
if ( !menu )
menu = wxFrame::MSWFindMenuFromHMENU(hMenu);
if ( !menu && m_windowMenu && GetHmenuOf(m_windowMenu) == hMenu )
menu = m_windowMenu;
return menu;
}
WXHMENU wxMDIParentFrame::MSWGetActiveMenu() const
{
wxMDIChildFrame * const child = GetActiveChild();