diff --git a/docs/changes.txt b/docs/changes.txt index d880ff3f80..df68cb53d5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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: diff --git a/include/wx/msw/mdi.h b/include/wx/msw/mdi.h index 867ea302c1..457414c949 100644 --- a/include/wx/msw/mdi.h +++ b/include/wx/msw/mdi.h @@ -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: diff --git a/samples/mdi/mdi.cpp b/samples/mdi/mdi.cpp index ee5acc77e7..bf6d57c3e6 100644 --- a/samples/mdi/mdi.cpp +++ b/samples/mdi/mdi.cpp @@ -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()); diff --git a/samples/mdi/mdi.h b/samples/mdi/mdi.h index cadb23695c..59612e2e6e 100644 --- a/samples/mdi/mdi.h +++ b/samples/mdi/mdi.h @@ -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 diff --git a/src/msw/mdi.cpp b/src/msw/mdi.cpp index 725d47ab49..b54b58580a 100644 --- a/src/msw/mdi.cpp +++ b/src/msw/mdi.cpp @@ -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();