From 2279b45ad97be45fc59105ac5ec54735d06bfa6f Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Sun, 17 Mar 2002 21:44:59 +0000 Subject: [PATCH] fix to segfault in system menu code git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14672 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/univ/themes/win32.cpp | 187 ++++++++++++++++++++------------------ 1 file changed, 101 insertions(+), 86 deletions(-) diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index ec3d13ca87..ca0b2fd4bc 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -602,8 +602,8 @@ class wxWin32SystemMenuEvtHandler; class wxWin32FrameInputHandler : public wxStdFrameInputHandler { public: - wxWin32FrameInputHandler(wxInputHandler *handler) - : wxStdFrameInputHandler(handler), m_menuHandler(NULL) { } + wxWin32FrameInputHandler(wxInputHandler *handler); + ~wxWin32FrameInputHandler(); virtual bool HandleMouse(wxInputConsumer *control, const wxMouseEvent& event); @@ -4350,79 +4350,13 @@ bool wxWin32StatusBarInputHandler::HandleMouseMove(wxInputConsumer *consumer, // wxWin32FrameInputHandler // ---------------------------------------------------------------------------- -bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer, - const wxMouseEvent& event) -{ - if ( event.LeftDClick() || event.LeftDown() || event.RightDown() ) - { - wxTopLevelWindow *tlw = - wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow); - - long hit = tlw->HitTest(event.GetPosition()); - - if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR ) - { - tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, - tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE - : wxTOPLEVEL_BUTTON_MAXIMIZE); - return TRUE; - } - else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU ) - { - if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) || - (event.RightDown() && - (hit == wxHT_TOPLEVEL_TITLEBAR || - hit == wxHT_TOPLEVEL_ICON)) ) - { - PopupSystemMenu(tlw, event.GetPosition()); - return TRUE; - } - } - } - - return wxStdFrameInputHandler::HandleMouse(consumer, event); -} - -void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window, - const wxPoint& pos) const -{ - wxMenu *menu = new wxMenu; - - if ( window->GetWindowStyle() & wxMAXIMIZE_BOX ) - menu->Append(wxID_RESTORE_FRAME , _("&Restore")); - menu->Append(wxID_MOVE_FRAME , _("&Move")); - if ( window->GetWindowStyle() & wxRESIZE_BORDER ) - menu->Append(wxID_RESIZE_FRAME , _("&Size")); - if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) ) - menu->Append(wxID_ICONIZE_FRAME , _("Mi&nimize")); - if ( window->GetWindowStyle() & wxMAXIMIZE_BOX ) - menu->Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize")); - menu->AppendSeparator(); - menu->Append(wxID_CLOSE_FRAME, _("Close\tAlt-F4")); - - if ( window->GetWindowStyle() & wxMAXIMIZE_BOX ) - { - if ( window->IsMaximized() ) - { - menu->Enable(wxID_MAXIMIZE_FRAME, FALSE); - menu->Enable(wxID_MOVE_FRAME, FALSE); - if ( window->GetWindowStyle() & wxRESIZE_BORDER ) - menu->Enable(wxID_RESIZE_FRAME, FALSE); - } - else - menu->Enable(wxID_RESTORE_FRAME, FALSE); - } - - window->PopupMenu(menu, pos); - delete menu; -} - class wxWin32SystemMenuEvtHandler : public wxEvtHandler { public: - wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler, - wxInputConsumer *consumer); - void RemoveSelf(); + wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler); + + void Attach(wxInputConsumer *consumer); + void Detach(); private: DECLARE_EVENT_TABLE() @@ -4436,10 +4370,16 @@ private: }; wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler( - wxWin32FrameInputHandler *handler, - wxInputConsumer *consumer) + wxWin32FrameInputHandler *handler) { m_inputHnd = handler; + m_wnd = NULL; +} + +void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer *consumer) +{ + wxASSERT_MSG( m_wnd == NULL, _T("can't attach the handler twice!") ); + m_wnd = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow); m_wnd->PushEventHandler(this); @@ -4452,12 +4392,13 @@ wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler( m_wnd->SetAcceleratorTable(table); } -void wxWin32SystemMenuEvtHandler::RemoveSelf() +void wxWin32SystemMenuEvtHandler::Detach() { if ( m_wnd ) { m_wnd->SetAcceleratorTable(m_oldAccelTable); m_wnd->RemoveEventHandler(this); + m_wnd = NULL; } } @@ -4496,25 +4437,99 @@ void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent &event) } -bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer, - bool activated) +wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler *handler) + : wxStdFrameInputHandler(handler) { - if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU ) + m_menuHandler = new wxWin32SystemMenuEvtHandler(this); +} + +wxWin32FrameInputHandler::~wxWin32FrameInputHandler() +{ + if ( m_menuHandler ) { - if ( !activated && m_menuHandler ) + m_menuHandler->Detach(); + delete m_menuHandler; + } +} + +bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer, + const wxMouseEvent& event) +{ + if ( event.LeftDClick() || event.LeftDown() || event.RightDown() ) + { + wxTopLevelWindow *tlw = + wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow); + + long hit = tlw->HitTest(event.GetPosition()); + + if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR ) { - m_menuHandler->RemoveSelf(); - wxDELETE(m_menuHandler); + tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, + tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE + : wxTOPLEVEL_BUTTON_MAXIMIZE); + return TRUE; } - else if ( activated ) + else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU ) { - if ( m_menuHandler ) + if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) || + (event.RightDown() && + (hit == wxHT_TOPLEVEL_TITLEBAR || + hit == wxHT_TOPLEVEL_ICON)) ) { - m_menuHandler->RemoveSelf(); - delete m_menuHandler; + PopupSystemMenu(tlw, event.GetPosition()); + return TRUE; } + } + } + + return wxStdFrameInputHandler::HandleMouse(consumer, event); +} - m_menuHandler = new wxWin32SystemMenuEvtHandler(this, consumer); +void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window, + const wxPoint& pos) const +{ + wxMenu *menu = new wxMenu; + + if ( window->GetWindowStyle() & wxMAXIMIZE_BOX ) + menu->Append(wxID_RESTORE_FRAME , _("&Restore")); + menu->Append(wxID_MOVE_FRAME , _("&Move")); + if ( window->GetWindowStyle() & wxRESIZE_BORDER ) + menu->Append(wxID_RESIZE_FRAME , _("&Size")); + if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) ) + menu->Append(wxID_ICONIZE_FRAME , _("Mi&nimize")); + if ( window->GetWindowStyle() & wxMAXIMIZE_BOX ) + menu->Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize")); + menu->AppendSeparator(); + menu->Append(wxID_CLOSE_FRAME, _("Close\tAlt-F4")); + + if ( window->GetWindowStyle() & wxMAXIMIZE_BOX ) + { + if ( window->IsMaximized() ) + { + menu->Enable(wxID_MAXIMIZE_FRAME, FALSE); + menu->Enable(wxID_MOVE_FRAME, FALSE); + if ( window->GetWindowStyle() & wxRESIZE_BORDER ) + menu->Enable(wxID_RESIZE_FRAME, FALSE); + } + else + menu->Enable(wxID_RESTORE_FRAME, FALSE); + } + + window->PopupMenu(menu, pos); + delete menu; +} + +bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer, + bool activated) +{ + if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU ) + { + // always detach if active frame changed: + m_menuHandler->Detach(); + + if ( activated ) + { + m_menuHandler->Attach(consumer); } } -- 2.45.2