home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / samples / menu / menu.cpp < prev    next >
C/C++ Source or Header  |  2002-12-16  |  25KB  |  819 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        samples/menu.cpp
  3. // Purpose:     wxMenu/wxMenuBar sample
  4. // Author:      Vadim Zeitlin
  5. // Modified by:
  6. // Created:     01.11.99
  7. // RCS-ID:      $Id: menu.cpp,v 1.26.2.1 2002/12/15 10:23:11 MBN Exp $
  8. // Copyright:   (c) 1999 Vadim Zeitlin
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. // For compilers that support precompilation, includes "wx/wx.h".
  21. #include "wx/wxprec.h"
  22.  
  23. #ifdef __BORLANDC__
  24.     #pragma hdrstop
  25. #endif
  26.  
  27. #ifndef WX_PRECOMP
  28.     #include "wx/app.h"
  29.     #include "wx/frame.h"
  30.     #include "wx/menu.h"
  31.     #include "wx/msgdlg.h"
  32.     #include "wx/log.h"
  33.     #include "wx/textctrl.h"
  34.     #include "wx/textdlg.h"
  35. #endif
  36.  
  37. #if !wxUSE_MENUS
  38.     // nice try...
  39.     #error "menu sample requires wxUSE_MENUS=1"
  40. #endif // wxUSE_MENUS
  41.  
  42. #include "copy.xpm"
  43.  
  44. // ----------------------------------------------------------------------------
  45. // classes
  46. // ----------------------------------------------------------------------------
  47.  
  48. // Define a new application
  49. class MyApp: public wxApp
  50. {
  51. public:
  52.     bool OnInit();
  53. };
  54.  
  55. // Define a new frame
  56. class MyFrame: public wxFrame
  57. {
  58. public:
  59.     MyFrame();
  60.  
  61.     virtual ~MyFrame();
  62.  
  63.     void LogMenuEvent(const wxCommandEvent& event);
  64.  
  65. protected:
  66.     void OnQuit(wxCommandEvent& event);
  67.     void OnClearLog(wxCommandEvent& event);
  68.  
  69.     void OnAbout(wxCommandEvent& event);
  70.  
  71.     void OnDummy(wxCommandEvent& event);
  72.  
  73.     void OnAppendMenuItem(wxCommandEvent& event);
  74.     void OnAppendSubMenu(wxCommandEvent& event);
  75.     void OnDeleteMenuItem(wxCommandEvent& event);
  76.     void OnInsertMenuItem(wxCommandEvent& event);
  77.     void OnCheckMenuItem(wxCommandEvent& event);
  78.     void OnEnableMenuItem(wxCommandEvent& event);
  79.     void OnGetLabelMenuItem(wxCommandEvent& event);
  80.     void OnSetLabelMenuItem(wxCommandEvent& event);
  81.     void OnGetMenuItemInfo(wxCommandEvent& event);
  82.  
  83.     void OnAppendMenu(wxCommandEvent& event);
  84.     void OnInsertMenu(wxCommandEvent& event);
  85.     void OnDeleteMenu(wxCommandEvent& event);
  86.     void OnToggleMenu(wxCommandEvent& event);
  87.     void OnEnableMenu(wxCommandEvent& event);
  88.     void OnGetLabelMenu(wxCommandEvent& event);
  89.     void OnSetLabelMenu(wxCommandEvent& event);
  90.  
  91.     void OnTestNormal(wxCommandEvent& event);
  92.     void OnTestCheck(wxCommandEvent& event);
  93.     void OnTestRadio(wxCommandEvent& event);
  94.  
  95. #ifdef __WXMSW__
  96.     void OnContextMenu(wxContextMenuEvent& event)
  97.         { ShowContextMenu(ScreenToClient(event.GetPosition())); }
  98. #else
  99.     void OnRightUp(wxMouseEvent& event)
  100.         { ShowContextMenu(event.GetPosition()); }
  101. #endif
  102.  
  103.     void OnMenuOpen(wxMenuEvent& event)
  104.         { LogMenuOpenOrClose(event, _T("opened")); }
  105.     void OnMenuClose(wxMenuEvent& event)
  106.         { LogMenuOpenOrClose(event, _T("closed")); }
  107.  
  108.     void OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event);
  109.  
  110.     void OnSize(wxSizeEvent& event);
  111.  
  112. private:
  113.     void LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what);
  114.     void ShowContextMenu(const wxPoint& pos);
  115.  
  116.     wxMenu *CreateDummyMenu(wxString *title);
  117.  
  118.     wxMenuItem *GetLastMenuItem() const;
  119.  
  120.     // the menu previously detached from the menubar (may be NULL)
  121.     wxMenu *m_menu;
  122.  
  123.     // the count of dummy menus already created
  124.     size_t m_countDummy;
  125.  
  126.     // the control used for logging
  127.     wxTextCtrl *m_textctrl;
  128.  
  129.     // the previous log target
  130.     wxLog *m_logOld;
  131.  
  132.     DECLARE_EVENT_TABLE()
  133. };
  134.  
  135. // A small helper class which intercepts all menu events and logs them
  136. class MyEvtHandler : public wxEvtHandler
  137. {
  138. public:
  139.     MyEvtHandler(MyFrame *frame) { m_frame = frame; }
  140.  
  141.     void OnMenuEvent(wxCommandEvent& event)
  142.     {
  143.         m_frame->LogMenuEvent(event);
  144.  
  145.         event.Skip();
  146.     }
  147.  
  148. private:
  149.     MyFrame *m_frame;
  150.  
  151.     DECLARE_EVENT_TABLE()
  152. };
  153.  
  154. // ----------------------------------------------------------------------------
  155. // constants
  156. // ----------------------------------------------------------------------------
  157.  
  158. enum
  159. {
  160.     Menu_File_Quit = 100,
  161.     Menu_File_ClearLog,
  162.  
  163.     Menu_MenuBar_Toggle = 200,
  164.     Menu_MenuBar_Append,
  165.     Menu_MenuBar_Insert,
  166.     Menu_MenuBar_Delete,
  167.     Menu_MenuBar_Enable,
  168.     Menu_MenuBar_GetLabel,
  169.     Menu_MenuBar_SetLabel,
  170.  
  171.     Menu_Menu_Append = 300,
  172.     Menu_Menu_AppendSub,
  173.     Menu_Menu_Insert,
  174.     Menu_Menu_Delete,
  175.     Menu_Menu_Enable,
  176.     Menu_Menu_Check,
  177.     Menu_Menu_GetLabel,
  178.     Menu_Menu_SetLabel,
  179.     Menu_Menu_GetInfo,
  180.  
  181.     Menu_Test_Normal = 400,
  182.     Menu_Test_Check,
  183.     Menu_Test_Radio1,
  184.     Menu_Test_Radio2,
  185.     Menu_Test_Radio3,
  186.  
  187.     Menu_Dummy_First = 500,
  188.     Menu_Dummy_Second,
  189.     Menu_Dummy_Third,
  190.     Menu_Dummy_Fourth,
  191.     Menu_Dummy_Last,
  192.  
  193.     Menu_Help_About = 1000,
  194.  
  195.     Menu_Popup_ToBeDeleted = 2000,
  196.     Menu_Popup_ToBeGreyed,
  197.     Menu_Popup_ToBeChecked,
  198.     Menu_Popup_Submenu,
  199.  
  200.     Menu_Max
  201. };
  202.  
  203. // ----------------------------------------------------------------------------
  204. // event tables
  205. // ----------------------------------------------------------------------------
  206.  
  207. BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  208.     EVT_MENU(Menu_File_Quit,     MyFrame::OnQuit)
  209.     EVT_MENU(Menu_File_ClearLog, MyFrame::OnClearLog)
  210.  
  211.     EVT_MENU(Menu_Help_About, MyFrame::OnAbout)
  212.  
  213.     EVT_MENU(Menu_MenuBar_Toggle,   MyFrame::OnToggleMenu)
  214.     EVT_MENU(Menu_MenuBar_Append,   MyFrame::OnAppendMenu)
  215.     EVT_MENU(Menu_MenuBar_Insert,   MyFrame::OnInsertMenu)
  216.     EVT_MENU(Menu_MenuBar_Delete,   MyFrame::OnDeleteMenu)
  217.     EVT_MENU(Menu_MenuBar_Enable,   MyFrame::OnEnableMenu)
  218.     EVT_MENU(Menu_MenuBar_GetLabel, MyFrame::OnGetLabelMenu)
  219.     EVT_MENU(Menu_MenuBar_SetLabel, MyFrame::OnSetLabelMenu)
  220.  
  221.     EVT_MENU(Menu_Menu_Append,    MyFrame::OnAppendMenuItem)
  222.     EVT_MENU(Menu_Menu_AppendSub, MyFrame::OnAppendSubMenu)
  223.     EVT_MENU(Menu_Menu_Insert,    MyFrame::OnInsertMenuItem)
  224.     EVT_MENU(Menu_Menu_Delete,    MyFrame::OnDeleteMenuItem)
  225.     EVT_MENU(Menu_Menu_Enable,    MyFrame::OnEnableMenuItem)
  226.     EVT_MENU(Menu_Menu_Check,     MyFrame::OnCheckMenuItem)
  227.     EVT_MENU(Menu_Menu_GetLabel,  MyFrame::OnGetLabelMenuItem)
  228.     EVT_MENU(Menu_Menu_SetLabel,  MyFrame::OnSetLabelMenuItem)
  229.     EVT_MENU(Menu_Menu_GetInfo,   MyFrame::OnGetMenuItemInfo)
  230.  
  231.     EVT_MENU(Menu_Test_Normal,    MyFrame::OnTestNormal)
  232.     EVT_MENU(Menu_Test_Check,     MyFrame::OnTestCheck)
  233.     EVT_MENU(Menu_Test_Radio1,    MyFrame::OnTestRadio)
  234.     EVT_MENU(Menu_Test_Radio2,    MyFrame::OnTestRadio)
  235.     EVT_MENU(Menu_Test_Radio3,    MyFrame::OnTestRadio)
  236.  
  237.     EVT_MENU_RANGE(Menu_Dummy_First, Menu_Dummy_Last, MyFrame::OnDummy)
  238.  
  239.     EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
  240.  
  241. #ifdef __WXMSW__
  242.     EVT_CONTEXT_MENU(MyFrame::OnContextMenu)
  243. #else
  244.     EVT_RIGHT_UP(MyFrame::OnRightUp)
  245. #endif
  246.  
  247.     EVT_MENU_OPEN(MyFrame::OnMenuOpen)
  248.     EVT_MENU_CLOSE(MyFrame::OnMenuClose)
  249.  
  250.     EVT_SIZE(MyFrame::OnSize)
  251. END_EVENT_TABLE()
  252.  
  253. BEGIN_EVENT_TABLE(MyEvtHandler, wxEvtHandler)
  254.     EVT_MENU(-1, MyEvtHandler::OnMenuEvent)
  255. END_EVENT_TABLE()
  256.  
  257. // ============================================================================
  258. // implementation
  259. // ============================================================================
  260.  
  261. // ----------------------------------------------------------------------------
  262. // MyApp
  263. // ----------------------------------------------------------------------------
  264.  
  265. IMPLEMENT_APP(MyApp)
  266.  
  267. // The `main program' equivalent, creating the windows and returning the
  268. // main frame
  269. bool MyApp::OnInit()
  270. {
  271.     // Create the main frame window
  272.     MyFrame* frame = new MyFrame;
  273.  
  274.     frame->Show(TRUE);
  275.  
  276. #if wxUSE_STATUSBAR
  277.     frame->SetStatusText(_T("Welcome to wxWindows menu sample"));
  278. #endif // wxUSE_STATUSBAR
  279.  
  280.     SetTopWindow(frame);
  281.  
  282.     return TRUE;
  283. }
  284.  
  285. // ----------------------------------------------------------------------------
  286. // MyFrame
  287. // ----------------------------------------------------------------------------
  288.  
  289. // Define my frame constructor
  290. MyFrame::MyFrame()
  291.        : wxFrame((wxFrame *)NULL, -1, _T("wxWindows menu sample"),
  292.                  wxDefaultPosition, wxSize(400, 250))
  293. {
  294.     m_textctrl = NULL;
  295.     m_menu = NULL;
  296.     m_countDummy = 0;
  297.     m_logOld = NULL;
  298.  
  299. #if wxUSE_STATUSBAR
  300.     CreateStatusBar();
  301. #endif // wxUSE_STATUSBAR
  302.  
  303.     // create the menubar
  304.     wxMenu *fileMenu = new wxMenu;
  305.  
  306.     wxMenuItem *item = new wxMenuItem(fileMenu, Menu_File_ClearLog,
  307.                                       _T("Clear &log\tCtrl-L"));
  308.     item->SetBitmap(copy_xpm);
  309.     fileMenu->Append(item);
  310.     fileMenu->AppendSeparator();
  311.     fileMenu->Append(Menu_File_Quit, _T("E&xit\tAlt-X"), _T("Quit menu sample"));
  312.  
  313.     wxMenu *menubarMenu = new wxMenu;
  314.     menubarMenu->Append(Menu_MenuBar_Append, _T("&Append menu\tCtrl-A"),
  315.                         _T("Append a menu to the menubar"));
  316.     menubarMenu->Append(Menu_MenuBar_Insert, _T("&Insert menu\tCtrl-I"),
  317.                         _T("Insert a menu into the menubar"));
  318.     menubarMenu->Append(Menu_MenuBar_Delete, _T("&Delete menu\tCtrl-D"),
  319.                         _T("Delete the last menu from the menubar"));
  320.     menubarMenu->Append(Menu_MenuBar_Toggle, _T("&Toggle menu\tCtrl-T"),
  321.                         _T("Toggle the first menu in the menubar"), TRUE);
  322.     menubarMenu->AppendSeparator();
  323.     menubarMenu->Append(Menu_MenuBar_Enable, _T("&Enable menu\tCtrl-E"),
  324.                         _T("Enable or disable the last menu"), TRUE);
  325.     menubarMenu->AppendSeparator();
  326.     menubarMenu->Append(Menu_MenuBar_GetLabel, _T("&Get menu label\tCtrl-G"),
  327.                         _T("Get the label of the last menu"));
  328.     menubarMenu->Append(Menu_MenuBar_SetLabel, _T("&Set menu label\tCtrl-S"),
  329.                         _T("Change the label of the last menu"));
  330.  
  331.     wxMenu *menuMenu = new wxMenu;
  332.     menuMenu->Append(Menu_Menu_Append, _T("&Append menu item\tAlt-A"),
  333.                      _T("Append a menu item to the last menu"));
  334.     menuMenu->Append(Menu_Menu_AppendSub, _T("&Append sub menu\tAlt-S"),
  335.                      _T("Append a sub menu to the last menu"));
  336.     menuMenu->Append(Menu_Menu_Insert, _T("&Insert menu item\tAlt-I"),
  337.                      _T("Insert a menu item in head of the last menu"));
  338.     menuMenu->Append(Menu_Menu_Delete, _T("&Delete menu item\tAlt-D"),
  339.                      _T("Delete the last menu item from the last menu"));
  340.     menuMenu->AppendSeparator();
  341.     menuMenu->Append(Menu_Menu_Enable, _T("&Enable menu item\tAlt-E"),
  342.                      _T("Enable or disable the last menu item"), TRUE);
  343.     menuMenu->Append(Menu_Menu_Check, _T("&Check menu item\tAlt-C"),
  344.                      _T("Check or uncheck the last menu item"), TRUE);
  345.     menuMenu->AppendSeparator();
  346.     menuMenu->Append(Menu_Menu_GetLabel, _T("&Get menu item label\tAlt-G"),
  347.                      _T("Get the label of the last menu item"));
  348.     menuMenu->Append(Menu_Menu_SetLabel, _T("&Set menu item label\tAlt-S"),
  349.                      _T("Change the label of the last menu item"));
  350.     menuMenu->AppendSeparator();
  351.     menuMenu->Append(Menu_Menu_GetInfo, _T("Get menu item in&fo\tAlt-F"),
  352.                      _T("Show the state of the last menu item"));
  353.  
  354.     wxMenu *testMenu = new wxMenu;
  355.     testMenu->Append(Menu_Test_Normal, _T("&Normal item"));
  356.     testMenu->AppendSeparator();
  357.     testMenu->AppendCheckItem(Menu_Test_Check, _T("&Check item"));
  358.     testMenu->AppendSeparator();
  359.     testMenu->AppendRadioItem(Menu_Test_Radio1, _T("Radio item &1"));
  360.     testMenu->AppendRadioItem(Menu_Test_Radio2, _T("Radio item &2"));
  361.     testMenu->AppendRadioItem(Menu_Test_Radio3, _T("Radio item &3"));
  362.  
  363.     wxMenu *helpMenu = new wxMenu;
  364.     helpMenu->Append(Menu_Help_About, _T("&About\tF1"), _T("About menu sample"));
  365.  
  366.     wxMenuBar* menuBar = new wxMenuBar( wxMB_DOCKABLE );
  367.  
  368.     menuBar->Append(fileMenu, _T("&File"));
  369.     menuBar->Append(menubarMenu, _T("Menu&bar"));
  370.     menuBar->Append(menuMenu, _T("&Menu"));
  371.     menuBar->Append(testMenu, _T("&Test"));
  372.     menuBar->Append(helpMenu, _T("&Help"));
  373.  
  374.     // these items should be initially checked
  375.     menuBar->Check(Menu_MenuBar_Toggle, TRUE);
  376.     menuBar->Check(Menu_MenuBar_Enable, TRUE);
  377.     menuBar->Check(Menu_Menu_Enable, TRUE);
  378.     menuBar->Check(Menu_Menu_Check, FALSE);
  379.  
  380.     // associate the menu bar with the frame
  381.     SetMenuBar(menuBar);
  382.  
  383.     // intercept all menu events and log them in this custom event handler
  384.     PushEventHandler(new MyEvtHandler(this));
  385.  
  386.     // create the log text window
  387.     m_textctrl = new wxTextCtrl(this, -1, _T(""),
  388.                                 wxDefaultPosition, wxDefaultSize,
  389.                                 wxTE_MULTILINE);
  390.     m_textctrl->SetEditable(FALSE);
  391.  
  392.     wxLog::SetTimestamp(NULL);
  393.     m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_textctrl));
  394.  
  395.     wxLogMessage(_T("Brief explanations: the commands or the \"Menu\" menu ")
  396.                  _T("append/insert/delete items to/from the last menu.\n")
  397.                  _T("The commands from \"Menubar\" menu work with the ")
  398.                  _T("menubar itself.\n\n")
  399.                  _T("Right click the band below to test popup menus.\n"));
  400. }
  401.  
  402. MyFrame::~MyFrame()
  403. {
  404.     delete m_menu;
  405.  
  406.     // delete the event handler installed in ctor
  407.     PopEventHandler(TRUE);
  408.  
  409.     // restore old logger
  410.     delete wxLog::SetActiveTarget(m_logOld);
  411. }
  412.  
  413. wxMenu *MyFrame::CreateDummyMenu(wxString *title)
  414. {
  415.     wxMenu *menu = new wxMenu;
  416.     menu->Append(Menu_Dummy_First, _T("&First item\tCtrl-F1"));
  417.     menu->AppendSeparator();
  418.     menu->Append(Menu_Dummy_Second, _T("&Second item\tCtrl-F2"), _T(""), TRUE);
  419.  
  420.     if ( title )
  421.     {
  422.         title->Printf(wxT("Dummy menu &%u"), (unsigned)++m_countDummy);
  423.     }
  424.  
  425.     return menu;
  426. }
  427.  
  428. wxMenuItem *MyFrame::GetLastMenuItem() const
  429. {
  430.     wxMenuBar *menubar = GetMenuBar();
  431.     wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
  432.  
  433.     wxMenuItemList::Node *node = menu->GetMenuItems().GetLast();
  434.     if ( !node )
  435.     {
  436.         wxLogWarning(wxT("No last item in the last menu!"));
  437.  
  438.         return NULL;
  439.     }
  440.     else
  441.     {
  442.         return node->GetData();
  443.     }
  444. }
  445.  
  446. void MyFrame::LogMenuEvent(const wxCommandEvent& event)
  447. {
  448.     int id = event.GetId();
  449.     if ( !GetMenuBar()->FindItem(id) )
  450.         return;
  451.  
  452.     wxString msg = wxString::Format(wxT("Menu command %d"), id);
  453.     if ( GetMenuBar()->FindItem(id)->IsCheckable() )
  454.     {
  455.         msg += wxString::Format(wxT(" (the item is currently %schecked)"),
  456.                                 event.IsChecked() ? "" : "not ");
  457.     }
  458.  
  459.     wxLogMessage(msg);
  460. }
  461.  
  462. // ----------------------------------------------------------------------------
  463. // menu callbacks
  464. // ----------------------------------------------------------------------------
  465.  
  466. void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
  467. {
  468.     Close(TRUE);
  469. }
  470.  
  471. void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
  472. {
  473.     m_textctrl->Clear();
  474. }
  475.  
  476. void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
  477. {
  478.     (void)wxMessageBox(_T("wxWindows menu sample\n⌐ 1999-2001 Vadim Zeitlin"),
  479.                        _T("About wxWindows menu sample"),
  480.                        wxICON_INFORMATION);
  481. }
  482.  
  483. void MyFrame::OnDeleteMenu(wxCommandEvent& WXUNUSED(event))
  484. {
  485.     wxMenuBar *mbar = GetMenuBar();
  486.  
  487.     size_t count = mbar->GetMenuCount();
  488.     if ( count == 2 )
  489.     {
  490.         // don't let delete the first 2 menus
  491.         wxLogError(wxT("Can't delete any more menus"));
  492.     }
  493.     else
  494.     {
  495.         delete mbar->Remove(count - 1);
  496.     }
  497. }
  498.  
  499. void MyFrame::OnInsertMenu(wxCommandEvent& WXUNUSED(event))
  500. {
  501.     wxString title;
  502.     wxMenu *menu = CreateDummyMenu(&title);
  503.     GetMenuBar()->Insert(0, menu, title);
  504. }
  505.  
  506. void MyFrame::OnAppendMenu(wxCommandEvent& WXUNUSED(event))
  507. {
  508.     wxString title;
  509.     wxMenu *menu = CreateDummyMenu(&title);
  510.     GetMenuBar()->Append(menu, title);
  511. }
  512.  
  513. void MyFrame::OnToggleMenu(wxCommandEvent& WXUNUSED(event))
  514. {
  515.     wxMenuBar *mbar = GetMenuBar();
  516.     if ( !m_menu )
  517.     {
  518.         // hide the menu
  519.         m_menu = mbar->Remove(0);
  520.     }
  521.     else
  522.     {
  523.         // restore it
  524.         mbar->Insert(0, m_menu, _T("&File"));
  525.         m_menu = NULL;
  526.     }
  527. }
  528.  
  529. void MyFrame::OnEnableMenu(wxCommandEvent& event)
  530. {
  531.     wxMenuBar *mbar = GetMenuBar();
  532.     size_t count = mbar->GetMenuCount();
  533.  
  534.     mbar->EnableTop(count - 1, event.IsChecked());
  535. }
  536.  
  537. void MyFrame::OnGetLabelMenu(wxCommandEvent& WXUNUSED(event))
  538. {
  539.     wxMenuBar *mbar = GetMenuBar();
  540.     size_t count = mbar->GetMenuCount();
  541.  
  542.     wxCHECK_RET( count, _T("no last menu?") );
  543.  
  544.     wxLogMessage(wxT("The label of the last menu item is '%s'"),
  545.                  mbar->GetLabelTop(count - 1).c_str());
  546. }
  547.  
  548. void MyFrame::OnSetLabelMenu(wxCommandEvent& WXUNUSED(event))
  549. {
  550.     wxMenuBar *mbar = GetMenuBar();
  551.     size_t count = mbar->GetMenuCount();
  552.  
  553.     wxCHECK_RET( count, _T("no last menu?") );
  554.  
  555.     wxString label = wxGetTextFromUser
  556.                      (
  557.                         _T("Enter new label: "),
  558.                         _T("Change last menu text"),
  559.                         mbar->GetLabelTop(count - 1),
  560.                         this
  561.                      );
  562.  
  563.     if ( !label.empty() )
  564.     {
  565.         mbar->SetLabelTop(count - 1, label);
  566.     }
  567. }
  568.  
  569. void MyFrame::OnDummy(wxCommandEvent& event)
  570. {
  571.     wxLogMessage(wxT("Dummy item #%d"), event.GetId() - Menu_Dummy_First + 1);
  572. }
  573.  
  574. void MyFrame::OnAppendMenuItem(wxCommandEvent& WXUNUSED(event))
  575. {
  576.     wxMenuBar *menubar = GetMenuBar();
  577.     wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
  578.  
  579.     menu->AppendSeparator();
  580.     menu->Append(Menu_Dummy_Third, _T("&Third dummy item\tCtrl-F3"),
  581.                  _T("Checkable item"), TRUE);
  582. }
  583.  
  584. void MyFrame::OnAppendSubMenu(wxCommandEvent& WXUNUSED(event))
  585. {
  586.     wxMenuBar *menubar = GetMenuBar();
  587.  
  588.     wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
  589.  
  590.     menu->Append(Menu_Dummy_Last, _T("&Dummy sub menu"),
  591.                  CreateDummyMenu(NULL), _T("Dummy sub menu help"));
  592. }
  593.  
  594. void MyFrame::OnDeleteMenuItem(wxCommandEvent& WXUNUSED(event))
  595. {
  596.     wxMenuBar *menubar = GetMenuBar();
  597.     wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
  598.  
  599.     size_t count = menu->GetMenuItemCount();
  600.     if ( !count )
  601.     {
  602.         wxLogWarning(wxT("No items to delete!"));
  603.     }
  604.     else
  605.     {
  606.         menu->Destroy(menu->GetMenuItems().Item(count - 1)->GetData());
  607.     }
  608. }
  609.  
  610. void MyFrame::OnInsertMenuItem(wxCommandEvent& WXUNUSED(event))
  611. {
  612.     wxMenuBar *menubar = GetMenuBar();
  613.     wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
  614.  
  615.     menu->Insert(0, wxMenuItem::New(menu, Menu_Dummy_Fourth,
  616.                                     _T("Fourth dummy item\tCtrl-F4")));
  617.     menu->Insert(1, wxMenuItem::New(menu, wxID_SEPARATOR, _T("")));
  618. }
  619.  
  620. void MyFrame::OnEnableMenuItem(wxCommandEvent& WXUNUSED(event))
  621. {
  622.     wxMenuItem *item = GetLastMenuItem();
  623.  
  624.     if ( item )
  625.     {
  626.         item->Enable(!item->IsEnabled());
  627.     }
  628. }
  629.  
  630. void MyFrame::OnCheckMenuItem(wxCommandEvent& WXUNUSED(event))
  631. {
  632.     wxMenuItem *item = GetLastMenuItem();
  633.  
  634.     item->Toggle();
  635. }
  636.  
  637. void MyFrame::OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event)
  638. {
  639.     wxLogNull nolog;
  640.  
  641.     wxMenuItem *item = GetLastMenuItem();
  642.  
  643.     event.Enable(item && item->IsCheckable());
  644. }
  645.  
  646. void MyFrame::OnGetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
  647. {
  648.     wxMenuItem *item = GetLastMenuItem();
  649.  
  650.     if ( item )
  651.     {
  652.         wxLogMessage(wxT("The label of the last menu item is '%s'"),
  653.                      item->GetLabel().c_str());
  654.     }
  655. }
  656.  
  657. void MyFrame::OnSetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
  658. {
  659.     wxMenuItem *item = GetLastMenuItem();
  660.  
  661.     if ( item )
  662.     {
  663.         wxString label = wxGetTextFromUser
  664.                          (
  665.                             _T("Enter new label: "),
  666.                             _T("Change last menu item text"),
  667.                             item->GetLabel(),
  668.                             this
  669.                          );
  670.  
  671.         if ( !label.empty() )
  672.         {
  673.             item->SetText(label);
  674.         }
  675.     }
  676. }
  677.  
  678. void MyFrame::OnGetMenuItemInfo(wxCommandEvent& WXUNUSED(event))
  679. {
  680.     wxMenuItem *item = GetLastMenuItem();
  681.  
  682.     if ( item )
  683.     {
  684.         wxString msg;
  685.         msg << _T("The item is ") << (item->IsEnabled() ? _T("enabled")
  686.                                                     : _T("disabled"))
  687.             << '\n';
  688.  
  689.         if ( item->IsCheckable() )
  690.         {
  691.             msg << _T("It is checkable and ") << (item->IsChecked() ? _T("") : _T("un"))
  692.                 << _T("checked\n");
  693.         }
  694.  
  695. #if wxUSE_ACCEL
  696.         wxAcceleratorEntry *accel = item->GetAccel();
  697.         if ( accel )
  698.         {
  699.             msg << _T("Its accelerator is ");
  700.  
  701.             int flags = accel->GetFlags();
  702.             if ( flags & wxACCEL_ALT )
  703.                 msg << wxT("Alt-");
  704.             if ( flags & wxACCEL_CTRL )
  705.                 msg << wxT("Ctrl-");
  706.             if ( flags & wxACCEL_SHIFT )
  707.                 msg << wxT("Shift-");
  708.  
  709.             int code = accel->GetKeyCode();
  710.             switch ( code )
  711.             {
  712.                 case WXK_F1:
  713.                 case WXK_F2:
  714.                 case WXK_F3:
  715.                 case WXK_F4:
  716.                 case WXK_F5:
  717.                 case WXK_F6:
  718.                 case WXK_F7:
  719.                 case WXK_F8:
  720.                 case WXK_F9:
  721.                 case WXK_F10:
  722.                 case WXK_F11:
  723.                 case WXK_F12:
  724.                     msg << wxT('F') << code - WXK_F1 + 1;
  725.                     break;
  726.  
  727.                 // if there are any other keys wxGetAccelFromString() may return,
  728.                 // we should process them here
  729.  
  730.                 default:
  731.                     if ( wxIsalnum(code) )
  732.                     {
  733.                         msg << (wxChar)code;
  734.  
  735.                         break;
  736.                     }
  737.  
  738.                     wxFAIL_MSG( wxT("unknown keyboard accel") );
  739.             }
  740.  
  741.             delete accel;
  742.         }
  743.         else
  744.         {
  745.             msg << _T("It doesn't have an accelerator");
  746.         }
  747. #endif // wxUSE_ACCEL
  748.  
  749.         wxLogMessage(msg);
  750.     }
  751. }
  752.  
  753. void MyFrame::ShowContextMenu(const wxPoint& pos)
  754. {
  755.     wxMenu menu(_T("Test popup"));
  756.  
  757.     menu.Append(Menu_Help_About, _T("&About"));
  758.     menu.Append(Menu_Popup_Submenu, _T("&Submenu"), CreateDummyMenu(NULL));
  759.     menu.Append(Menu_Popup_ToBeDeleted, _T("To be &deleted"));
  760.     menu.Append(Menu_Popup_ToBeChecked, _T("To be &checked"), _T(""), TRUE);
  761.     menu.Append(Menu_Popup_ToBeGreyed, _T("To be &greyed"));
  762.     menu.AppendSeparator();
  763.     menu.Append(Menu_File_Quit, _T("E&xit"));
  764.  
  765.     menu.Delete(Menu_Popup_ToBeDeleted);
  766.     menu.Check(Menu_Popup_ToBeChecked, TRUE);
  767.     menu.Enable(Menu_Popup_ToBeGreyed, FALSE);
  768.  
  769.     PopupMenu(&menu, pos.x, pos.y);
  770.  
  771.     // test for destroying items in popup menus
  772. #if 0 // doesn't work in wxGTK!
  773.     menu.Destroy(Menu_Popup_Submenu);
  774.  
  775.     PopupMenu( &menu, event.GetX(), event.GetY() );
  776. #endif // 0
  777. }
  778.  
  779. void MyFrame::OnTestNormal(wxCommandEvent& event)
  780. {
  781.     wxLogMessage(_T("Normal item selected"));
  782. }
  783.  
  784. void MyFrame::OnTestCheck(wxCommandEvent& event)
  785. {
  786.     wxLogMessage(_T("Check item %schecked"),
  787.                  event.IsChecked() ? _T("") : _T("un"));
  788. }
  789.  
  790. void MyFrame::OnTestRadio(wxCommandEvent& event)
  791. {
  792.     wxLogMessage(_T("Radio item %d selected"),
  793.                  event.GetId() - Menu_Test_Radio1 + 1);
  794. }
  795.  
  796. void MyFrame::LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what)
  797. {
  798.     wxLogStatus(this, _T("A %smenu has been %s."),
  799.                 event.IsPopup() ? _T("popup ") : _T(""), what);
  800. }
  801.  
  802. void MyFrame::OnSize(wxSizeEvent& event)
  803. {
  804.     if ( !m_textctrl )
  805.         return;
  806.  
  807.     // leave a band below for popup menu testing
  808.     wxSize size = GetClientSize();
  809.     m_textctrl->SetSize(0, 0, size.x, (3*size.y)/4);
  810.  
  811.     // this is really ugly but we have to do it as we can't just call
  812.     // event.Skip() because wxFrameBase would make the text control fill the
  813.     // entire frame then
  814. #ifdef __WXUNIVERSAL__
  815.     PositionMenuBar();
  816. #endif // __WXUNIVERSAL__
  817. }
  818.  
  819.