diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 449ad39e3f..9438c25267 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -664,7 +664,20 @@ bool wxWindowMSW::Show(bool show) // should work without errors if ( hWnd ) { - ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); + BOOL ret = ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); + + // Windows does not generate its WM_SHOWWINDOW notification when hiding + // a frozen window. Instead, ::ShowWindow() returns that the window was + // previously hidden, although it was shown but frozen. + // In such a case we have to generate the wxEVT_SHOW event ourselves + // for a consistent behaviour under all platforms. + bool changed = (ret != 0) != show; + if ( !changed && IsFrozen() ) + { + wxShowEvent eventShow(GetId(), show); + eventShow.SetEventObject(this); + HandleWindowEvent(eventShow); + } } if ( IsFrozen() ) diff --git a/tests/controls/notebooktest.cpp b/tests/controls/notebooktest.cpp index 63c5f625fa..561ae35b99 100644 --- a/tests/controls/notebooktest.cpp +++ b/tests/controls/notebooktest.cpp @@ -18,6 +18,7 @@ #include "wx/notebook.h" #include "wx/scopedptr.h" +#include "wx/wupdlock.h" #include "bookctrlbasetest.h" #include "testableframe.h" @@ -118,6 +119,130 @@ void NotebookTestCase::NoEventsOnDestruction() CHECK( m_numPageChanges == 1 ); } +// Unfortunately currently wxMSW is the only port in which wxEVT_SHOW events +// are generated for the notebook pages as expected. +#ifdef __WXMSW__ + #define wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES +#endif + +#ifdef wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + +enum EvtShowState +{ + // According to the last wxEVT_SHOW notification, ... + EvtShowState_Hidden, // ... the window has been hidden + EvtShowState_Shown // ... the window has been shown +}; + +class NotebookPage : public wxPanel +{ +public: + NotebookPage(wxWindow *parent, wxWindowID id = wxID_ANY); + + // Returns the current display state (shown or hidden) according to + // the last wxEVT_SHOW notification received. + EvtShowState GetEvtShowState() const { return m_evtShowState; } + +protected: + void OnShow(wxShowEvent& event); + + EvtShowState m_evtShowState; +}; + +NotebookPage::NotebookPage(wxWindow *parent, wxWindowID id) + : wxPanel(parent, id) +{ + // Windows that are not derived from wxTopLevelWindow are + // by default created in the shown state. + m_evtShowState = EvtShowState_Shown; + + Bind(wxEVT_SHOW, &NotebookPage::OnShow, this); +} + +void NotebookPage::OnShow(wxShowEvent& event) +{ + m_evtShowState = event.IsShown() ? EvtShowState_Shown + : EvtShowState_Hidden; + + event.Skip(); +} + +#else // !wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + +typedef wxPanel NotebookPage; + +#endif // wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + +static void DoTestAddPageEvents(wxNotebook* notebook) +{ + EventCounter countPageChanging(notebook, wxEVT_NOTEBOOK_PAGE_CHANGING); + EventCounter countPageChanged(notebook, wxEVT_NOTEBOOK_PAGE_CHANGED); + + // Add the first page, it is special. + NotebookPage* page1 = new NotebookPage(notebook); + notebook->AddPage(page1, "Initial page"); + + // The selection should have been changed. + CHECK( notebook->GetSelection() == 0 ); + + // But no events should have been generated. + CHECK( countPageChanging.GetCount() == 0 ); + CHECK( countPageChanged.GetCount() == 0 ); + +#ifdef wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + CHECK( page1->GetEvtShowState() == EvtShowState_Shown ); +#endif // wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + + + // Add another page without selecting it. + NotebookPage* page2 = new NotebookPage(notebook); + notebook->AddPage(page2, "Unselected page"); + + // Selection shouldn't have changed. + CHECK( notebook->GetSelection() == 0 ); + + // And no events should have been generated, of course. + CHECK( countPageChanging.GetCount() == 0 ); + CHECK( countPageChanged.GetCount() == 0 ); + +#ifdef wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + CHECK( page1->GetEvtShowState() == EvtShowState_Shown ); + CHECK( page2->GetEvtShowState() == EvtShowState_Hidden ); +#endif // wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + + + // Finally add another page and do select it. + NotebookPage* page3 = new NotebookPage(notebook); + notebook->AddPage(page3, "Selected page", true); + + // It should have become selected. + CHECK( notebook->GetSelection() == 2 ); + + // And events for the selection change should have been generated. + CHECK( countPageChanging.GetCount() == 1 ); + CHECK( countPageChanged.GetCount() == 1 ); + +#ifdef wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + CHECK( page1->GetEvtShowState() == EvtShowState_Hidden ); + CHECK( page2->GetEvtShowState() == EvtShowState_Hidden ); + CHECK( page3->GetEvtShowState() == EvtShowState_Shown ); +#endif // wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + + + // Change the selection to the first page. + notebook->SetSelection(0); + + // And events for the selection change should have been generated. + CHECK( countPageChanging.GetCount() == 2 ); + CHECK( countPageChanged.GetCount() == 2 ); + +#ifdef wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES + CHECK( page1->GetEvtShowState() == EvtShowState_Shown ); + CHECK( page2->GetEvtShowState() == EvtShowState_Hidden ); + CHECK( page3->GetEvtShowState() == EvtShowState_Hidden ); +#endif // wxHAS_WORKING_SHOW_EVENTS_FOR_NOTEBOOK_PAGES +} + TEST_CASE("wxNotebook::AddPageEvents", "[wxNotebook][AddPage][event]") { wxNotebook* const @@ -127,40 +252,18 @@ TEST_CASE("wxNotebook::AddPageEvents", "[wxNotebook][AddPage][event]") CHECK( notebook->GetSelection() == wxNOT_FOUND ); - EventCounter countPageChanging(notebook, wxEVT_NOTEBOOK_PAGE_CHANGING); - EventCounter countPageChanged(notebook, wxEVT_NOTEBOOK_PAGE_CHANGED); + SECTION("Normal notebook") + { + DoTestAddPageEvents(notebook); + } - // Add the first page, it is special. - notebook->AddPage(new wxPanel(notebook), "Initial page"); + SECTION("Frozen notebook") + { + wxWindowUpdateLocker noUpdates(notebook); + REQUIRE( notebook->IsFrozen() ); - // The selection should have been changed. - CHECK( notebook->GetSelection() == 0 ); - - // But no events should have been generated. - CHECK( countPageChanging.GetCount() == 0 ); - CHECK( countPageChanged.GetCount() == 0 ); - - - // Add another page without selecting it. - notebook->AddPage(new wxPanel(notebook), "Unselected page"); - - // Selection shouldn't have changed. - CHECK( notebook->GetSelection() == 0 ); - - // And no events should have been generated, of course. - CHECK( countPageChanging.GetCount() == 0 ); - CHECK( countPageChanged.GetCount() == 0 ); - - - // Finally add another page and do select it. - notebook->AddPage(new wxPanel(notebook), "Selected page", true); - - // It should have become selected. - CHECK( notebook->GetSelection() == 2 ); - - // And events for the selection change should have been generated. - CHECK( countPageChanging.GetCount() == 1 ); - CHECK( countPageChanged.GetCount() == 1 ); + DoTestAddPageEvents(notebook); + } } #endif //wxUSE_NOTEBOOK diff --git a/tests/controls/windowtest.cpp b/tests/controls/windowtest.cpp index a0dce6b2f4..ac9b777c94 100644 --- a/tests/controls/windowtest.cpp +++ b/tests/controls/windowtest.cpp @@ -26,6 +26,7 @@ #include "wx/scopedptr.h" #include "wx/stopwatch.h" #include "wx/tooltip.h" +#include "wx/wupdlock.h" class WindowTestCase { @@ -53,25 +54,43 @@ protected: wxDECLARE_NO_COPY_CLASS(WindowTestCase); }; -TEST_CASE_METHOD(WindowTestCase, "Window::ShowHideEvent", "[window]") -{ #if defined(__WXMSW__) - EventCounter show(m_window, wxEVT_SHOW); - CHECK(m_window->IsShown()); +static void DoTestShowHideEvent(wxWindow* window) +{ + EventCounter show(window, wxEVT_SHOW); - m_window->Show(false); + CHECK(window->IsShown()); - CHECK(!m_window->IsShown()); + window->Show(false); - m_window->Show(); + CHECK(!window->IsShown()); - CHECK(m_window->IsShown()); + window->Show(); + + CHECK(window->IsShown()); CHECK( show.GetCount() == 2 ); -#endif // __WXMSW__ } +TEST_CASE_METHOD(WindowTestCase, "Window::ShowHideEvent", "[window]") +{ + SECTION("Normal window") + { + DoTestShowHideEvent(m_window); + } + + SECTION("Frozen window") + { + wxWindowUpdateLocker freeze(m_window->GetParent() ); + REQUIRE( m_window->IsFrozen() ); + + DoTestShowHideEvent(m_window); + } +} + +#endif // __WXMSW__ + TEST_CASE_METHOD(WindowTestCase, "Window::KeyEvent", "[window]") { #if wxUSE_UIACTIONSIMULATOR