+// Helper for checking that the menu event processing resulted in the expected
+// output from the handlers.
+void CheckMenuEvent(wxMenu* menu, const char* expected)
+{
+ g_str.clear();
+
+ // Trigger the menu event: this is more reliable than using
+ // wxUIActionSimulator and currently works in all ports as they all call
+ // wxMenuBase::SendEvent() from their respective menu event handlers.
+ menu->SendEvent(wxID_NEW);
+
+ CPPUNIT_ASSERT_EQUAL( expected, g_str );
+}
+
+void EventPropagationTestCase::MenuEvent()
+{
+ // Create a minimal menu bar.
+ wxMenu* const menu = new wxMenu;
+ menu->Append(wxID_NEW);
+ wxMenuBar* const mb = new wxMenuBar;
+ mb->Append(menu, "&Menu");
+
+ wxFrame* const frame = static_cast<wxFrame*>(wxTheApp->GetTopWindow());
+ frame->SetMenuBar(mb);
+ wxON_BLOCK_EXIT_OBJ1( *frame, wxFrame::SetMenuBar, (wxMenuBar*)NULL );
+
+ // Check that wxApp gets the event exactly once.
+ CheckMenuEvent( menu, "aA" );
+
+
+ // Check that the menu event handler is called.
+ TestMenuEvtHandler hm('m'); // 'm' for "menu"
+ menu->SetNextHandler(&hm);
+ wxON_BLOCK_EXIT_OBJ1( *menu,
+ wxEvtHandler::SetNextHandler, (wxEvtHandler*)NULL );
+ CheckMenuEvent( menu, "aomA" );
+
+
+ // Also test that the window to which the menu belongs gets the event.
+ TestMenuEvtHandler hw('w'); // 'w' for "Window"
+ frame->PushEventHandler(&hw);
+ wxON_BLOCK_EXIT_OBJ1( *frame, wxWindow::PopEventHandler, false );
+
+ CheckMenuEvent( menu, "aomowA" );
+}