home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / samples / listbox / lboxtest.cpp next >
C/C++ Source or Header  |  2000-10-20  |  22KB  |  688 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        lboxtest.cpp
  3. // Purpose:     wxListBox sample
  4. // Author:      Vadim Zeitlin
  5. // Id:          $Id: lboxtest.cpp,v 1.2 2000/10/19 23:58:42 vadz Exp $
  6. // Copyright:   (c) 2000 Vadim Zeitlin
  7. // Licence:     wxWindows licence
  8. /////////////////////////////////////////////////////////////////////////////
  9.  
  10. /*
  11.    Current bugs:
  12.  
  13.   +1. horz scrollbar doesn't appear in listbox
  14.   +2. truncating text ctrl doesn't update display
  15.   +3. deleting last listbox item doesn't update display
  16.    4. text ctrl background corrupted after resize
  17.  */
  18.  
  19. // ============================================================================
  20. // declarations
  21. // ============================================================================
  22.  
  23. #ifdef __GNUG__
  24.     #pragma implementation "lboxtest.cpp"
  25.     #pragma interface "lboxtest.cpp"
  26. #endif
  27.  
  28. // ----------------------------------------------------------------------------
  29. // headers
  30. // ----------------------------------------------------------------------------
  31.  
  32. // for compilers that support precompilation, includes "wx/wx.h".
  33. #include "wx/wxprec.h"
  34.  
  35. #ifdef __BORLANDC__
  36.     #pragma hdrstop
  37. #endif
  38.  
  39. // for all others, include the necessary headers
  40. #ifndef WX_PRECOMP
  41.     #include "wx/app.h"
  42.     #include "wx/frame.h"
  43.     #include "wx/dcclient.h"
  44.  
  45.     #include "wx/button.h"
  46.     #include "wx/checkbox.h"
  47.     #include "wx/checklst.h"
  48.     #include "wx/listbox.h"
  49.     #include "wx/radiobox.h"
  50.     #include "wx/radiobut.h"
  51.     #include "wx/statbox.h"
  52.     #include "wx/stattext.h"
  53.     #include "wx/textctrl.h"
  54. #endif
  55.  
  56. #include "wx/sizer.h"
  57.  
  58. #ifdef __WXUNIVERSAL__
  59.     #include "wx/univ/theme.h"
  60. #endif // __WXUNIVERSAL__
  61.  
  62. // ----------------------------------------------------------------------------
  63. // constants
  64. // ----------------------------------------------------------------------------
  65.  
  66. // control ids
  67. enum
  68. {
  69.     LboxTest_Reset = 100,
  70.     LboxTest_Create,
  71.     LboxTest_Add,
  72.     LboxTest_AddText,
  73.     LboxTest_AddSeveral,
  74.     LboxTest_AddMany,
  75.     LboxTest_Clear,
  76.     LboxTest_ClearLog,
  77.     LboxTest_Change,
  78.     LboxTest_ChangeText,
  79.     LboxTest_Delete,
  80.     LboxTest_DeleteText,
  81.     LboxTest_DeleteSel,
  82.     LboxTest_Listbox,
  83.     LboxTest_Quit
  84. };
  85.  
  86. // ----------------------------------------------------------------------------
  87. // our classes
  88. // ----------------------------------------------------------------------------
  89.  
  90. // Define a new application type, each program should derive a class from wxApp
  91. class LboxTestApp : public wxApp
  92. {
  93. public:
  94.     // override base class virtuals
  95.     // ----------------------------
  96.  
  97.     // this one is called on application startup and is a good place for the app
  98.     // initialization (doing it here and not in the ctor allows to have an error
  99.     // return: if OnInit() returns false, the application terminates)
  100.     virtual bool OnInit();
  101. };
  102.  
  103. // Define a new frame type: this is going to be our main frame
  104. class LboxTestFrame : public wxFrame
  105. {
  106. public:
  107.     // ctor(s) and dtor
  108.     LboxTestFrame(const wxString& title);
  109.     virtual ~LboxTestFrame();
  110.  
  111. protected:
  112.     // event handlers
  113.     void OnButtonReset(wxCommandEvent& event);
  114.     void OnButtonCreate(wxCommandEvent& event);
  115.     void OnButtonChange(wxCommandEvent& event);
  116.     void OnButtonDelete(wxCommandEvent& event);
  117.     void OnButtonDeleteSel(wxCommandEvent& event);
  118.     void OnButtonClear(wxCommandEvent& event);
  119.     void OnButtonClearLog(wxCommandEvent& event);
  120.     void OnButtonAdd(wxCommandEvent& event);
  121.     void OnButtonAddSeveral(wxCommandEvent& event);
  122.     void OnButtonAddMany(wxCommandEvent& event);
  123.     void OnButtonQuit(wxCommandEvent& event);
  124.  
  125.     void OnListbox(wxCommandEvent& event);
  126.     void OnListboxDClick(wxCommandEvent& event);
  127.  
  128.     void OnCheckOrRadioBox(wxCommandEvent& event);
  129.  
  130.     void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
  131.     void OnUpdateUICreateButton(wxUpdateUIEvent& event);
  132.     void OnUpdateUIClearButton(wxUpdateUIEvent& event);
  133.     void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
  134.     void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event);
  135.  
  136.     // reset the listbox parameters
  137.     void Reset();
  138.  
  139.     // (re)create the listbox
  140.     void CreateLbox();
  141.  
  142.     // listbox parameters
  143.     // ------------------
  144.  
  145.     // the selection mode
  146.     enum LboxSelection
  147.     {
  148.         LboxSel_Single,
  149.         LboxSel_Extended,
  150.         LboxSel_Multiple
  151.     } m_lboxSelMode;
  152.  
  153.     // should it be sorted?
  154.     bool m_sorted;
  155.  
  156.     // should it have horz scroll/vert scrollbar permanently shown?
  157.     bool m_horzScroll,
  158.          m_vertScrollAlways;
  159.  
  160.     // should the recreate button be enabled?
  161.     bool m_dirty;
  162.  
  163.     // the controls
  164.     // ------------
  165.  
  166.     // the sel mode radiobox
  167.     wxRadioBox *m_radioSelMode;
  168.  
  169.     // the checkboxes
  170.     wxCheckBox *m_chkSort,
  171.                *m_chkHScroll,
  172.                *m_chkVScroll;
  173.  
  174.     // the listbox itself and the sizer it is in
  175.     wxListBox *m_lbox;
  176.     wxSizer *m_sizerLbox;
  177.  
  178.     // the listbox for logging messages
  179.     wxListBox *m_lboxLog;
  180.  
  181.     // the text entries for "Add/change string" and "Delete" buttons
  182.     wxTextCtrl *m_textAdd,
  183.                *m_textChange,
  184.                *m_textDelete;
  185.  
  186. private:
  187.     // the log target we use to redirect messages to the listbox
  188.     wxLog *m_logTarget;
  189.  
  190.     // any class wishing to process wxWindows events must use this macro
  191.     DECLARE_EVENT_TABLE()
  192. };
  193.  
  194. // A log target which just redirects the messages to a listbox
  195. class LboxLogger : public wxLog
  196. {
  197. public:
  198.     LboxLogger(wxListBox *lbox, wxLog *logOld)
  199.     {
  200.         m_lbox = lbox;
  201.         //m_lbox->Disable(); -- looks ugly under MSW
  202.         m_logOld = logOld;
  203.     }
  204.  
  205.     virtual ~LboxLogger()
  206.     {
  207.         wxLog::SetActiveTarget(m_logOld);
  208.     }
  209.  
  210. private:
  211.     // implement sink functions
  212.     virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t)
  213.     {
  214.         // don't put trace messages into listbox or we can get into infinite
  215.         // recursion
  216.         if ( level == wxLOG_Trace )
  217.         {
  218.             if ( m_logOld )
  219.             {
  220.                 // cast is needed to call protected method
  221.                 ((LboxLogger *)m_logOld)->DoLog(level, szString, t);
  222.             }
  223.         }
  224.         else
  225.         {
  226.             wxLog::DoLog(level, szString, t);
  227.         }
  228.     }
  229.  
  230.     virtual void DoLogString(const wxChar *szString, time_t t)
  231.     {
  232.         wxString msg;
  233.         TimeStamp(&msg);
  234.         msg += szString;
  235.         #ifdef __WXUNIVERSAL__
  236.             m_lbox->AppendAndEnsureVisible(msg);
  237.         #else // other ports don't have this method yet
  238.             m_lbox->Append(msg);
  239.  
  240.             // SetFirstItem() isn't implemented in wxGTK
  241.             #ifndef __WXGTK__
  242.                 m_lbox->SetFirstItem(m_lbox->GetCount() - 1);
  243.             #endif
  244.         #endif
  245.     }
  246.  
  247.     // the control we use
  248.     wxListBox *m_lbox;
  249.  
  250.     // the old log target
  251.     wxLog *m_logOld;
  252. };
  253.  
  254. // ----------------------------------------------------------------------------
  255. // misc macros
  256. // ----------------------------------------------------------------------------
  257.  
  258. IMPLEMENT_APP(LboxTestApp)
  259.  
  260. #ifdef __WXUNIVERSAL__
  261.     WX_USE_THEME(win32);
  262.     WX_USE_THEME(gtk);
  263. #endif // __WXUNIVERSAL__
  264.  
  265. // ----------------------------------------------------------------------------
  266. // event tables
  267. // ----------------------------------------------------------------------------
  268.  
  269. BEGIN_EVENT_TABLE(LboxTestFrame, wxFrame)
  270.     EVT_BUTTON(LboxTest_Reset, LboxTestFrame::OnButtonReset)
  271.     EVT_BUTTON(LboxTest_Create, LboxTestFrame::OnButtonCreate)
  272.     EVT_BUTTON(LboxTest_Change, LboxTestFrame::OnButtonChange)
  273.     EVT_BUTTON(LboxTest_Delete, LboxTestFrame::OnButtonDelete)
  274.     EVT_BUTTON(LboxTest_DeleteSel, LboxTestFrame::OnButtonDeleteSel)
  275.     EVT_BUTTON(LboxTest_Clear, LboxTestFrame::OnButtonClear)
  276.     EVT_BUTTON(LboxTest_ClearLog, LboxTestFrame::OnButtonClearLog)
  277.     EVT_BUTTON(LboxTest_Add, LboxTestFrame::OnButtonAdd)
  278.     EVT_BUTTON(LboxTest_AddSeveral, LboxTestFrame::OnButtonAddSeveral)
  279.     EVT_BUTTON(LboxTest_AddMany, LboxTestFrame::OnButtonAddMany)
  280.     EVT_BUTTON(LboxTest_Quit, LboxTestFrame::OnButtonQuit)
  281.  
  282.     EVT_TEXT_ENTER(LboxTest_AddText, LboxTestFrame::OnButtonAdd)
  283.     EVT_TEXT_ENTER(LboxTest_DeleteText, LboxTestFrame::OnButtonDelete)
  284.  
  285.     EVT_UPDATE_UI_RANGE(LboxTest_Reset, LboxTest_Create,
  286.                         LboxTestFrame::OnUpdateUICreateButton)
  287.  
  288.     EVT_UPDATE_UI(LboxTest_AddSeveral, LboxTestFrame::OnUpdateUIAddSeveral)
  289.     EVT_UPDATE_UI(LboxTest_Clear, LboxTestFrame::OnUpdateUIClearButton)
  290.     EVT_UPDATE_UI(LboxTest_DeleteText, LboxTestFrame::OnUpdateUIClearButton)
  291.     EVT_UPDATE_UI(LboxTest_Delete, LboxTestFrame::OnUpdateUIDeleteButton)
  292.     EVT_UPDATE_UI(LboxTest_Change, LboxTestFrame::OnUpdateUIDeleteSelButton)
  293.     EVT_UPDATE_UI(LboxTest_ChangeText, LboxTestFrame::OnUpdateUIDeleteSelButton)
  294.     EVT_UPDATE_UI(LboxTest_DeleteSel, LboxTestFrame::OnUpdateUIDeleteSelButton)
  295.  
  296.     EVT_LISTBOX(LboxTest_Listbox, LboxTestFrame::OnListbox)
  297.     EVT_LISTBOX_DCLICK(-1, LboxTestFrame::OnListboxDClick)
  298.     EVT_CHECKBOX(-1, LboxTestFrame::OnCheckOrRadioBox)
  299.     EVT_RADIOBOX(-1, LboxTestFrame::OnCheckOrRadioBox)
  300. END_EVENT_TABLE()
  301.  
  302. // ============================================================================
  303. // implementation
  304. // ============================================================================
  305.  
  306. // ----------------------------------------------------------------------------
  307. // app class
  308. // ----------------------------------------------------------------------------
  309.  
  310. bool LboxTestApp::OnInit()
  311. {
  312.     wxFrame *frame = new LboxTestFrame(_T("wxListBox sample"));
  313.     frame->Show();
  314.  
  315.     //wxLog::AddTraceMask(_T("listbox"));
  316.     wxLog::AddTraceMask(_T("scrollbar"));
  317.  
  318.     return TRUE;
  319. }
  320.  
  321. // ----------------------------------------------------------------------------
  322. // top level frame class
  323. // ----------------------------------------------------------------------------
  324.  
  325. LboxTestFrame::LboxTestFrame(const wxString& title)
  326.              : wxFrame(NULL, -1, title, wxPoint(100, 100))
  327. {
  328.     // init everything
  329.     m_dirty = FALSE;
  330.     m_radioSelMode = (wxRadioBox *)NULL;
  331.  
  332.     m_chkVScroll =
  333.     m_chkHScroll =
  334.     m_chkSort = (wxCheckBox *)NULL;
  335.  
  336.     m_lbox =
  337.     m_lboxLog = (wxListBox *)NULL;
  338.     m_sizerLbox = (wxSizer *)NULL;
  339.  
  340.     m_logTarget = (wxLog *)NULL;
  341.  
  342.     wxPanel *panel = new wxPanel(this, -1);
  343.  
  344.     /*
  345.        What we create here is a frame having 3 panes: the explanatory pane to
  346.        the left allowing to set the listbox styles and recreate the control,
  347.        the pane containing the listbox itself and the lower pane containing
  348.        the buttons which allow to add/change/delete strings to/from it.
  349.     */
  350.     wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL),
  351.             *sizerUp = new wxBoxSizer(wxHORIZONTAL),
  352.             *sizerLeft,
  353.             *sizerRight = new wxBoxSizer(wxVERTICAL);
  354.  
  355.     // upper left pane
  356.     static const wxString modes[] =
  357.     {
  358.         _T("single"),
  359.         _T("extended"),
  360.         _T("multiple"),
  361.     };
  362.  
  363.     wxStaticBox *box = new wxStaticBox(panel, -1, _T("&Set listbox parameters"));
  364.     m_radioSelMode = new wxRadioBox(panel, -1, _T("Selection &mode:"),
  365.                                     wxDefaultPosition, wxDefaultSize,
  366.                                     WXSIZEOF(modes), modes,
  367.                                     1, wxRA_SPECIFY_COLS);
  368.  
  369.     m_chkVScroll = new wxCheckBox(panel, -1, _T("Always show &vertical scrollbar"));
  370.     m_chkHScroll = new wxCheckBox(panel, -1, _T("Show &horizontal scrollbar"));
  371.     m_chkSort = new wxCheckBox(panel, -1, _T("&Sort items"));
  372.  
  373.     sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
  374.  
  375.     sizerLeft->Add(m_chkVScroll, 0, wxLEFT | wxRIGHT, 5);
  376.     sizerLeft->Add(m_chkHScroll, 0, wxLEFT | wxRIGHT, 5);
  377.     sizerLeft->Add(m_chkSort, 0, wxLEFT | wxRIGHT, 5);
  378.     sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
  379.     sizerLeft->Add(m_radioSelMode, 0, wxGROW | wxALL, 5);
  380.  
  381.     wxSizer *sizerBtn = new wxBoxSizer(wxHORIZONTAL);
  382.     wxButton *btn = new wxButton(panel, LboxTest_Reset, _T("&Reset"));
  383.     sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5);
  384.     btn = new wxButton(panel, LboxTest_Create, _T("&Create"));
  385.     sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5);
  386.     sizerLeft->Add(sizerBtn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
  387.  
  388.     // middle pane
  389.     wxStaticBox *box2 = new wxStaticBox(panel, -1, _T("&Change listbox contents"));
  390.     wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
  391.  
  392.     wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
  393.     btn = new wxButton(panel, LboxTest_Add, _T("&Add this string"));
  394.     m_textAdd = new wxTextCtrl(panel, LboxTest_AddText, _T("test item 0"));
  395.     sizerRow->Add(btn, 0, wxRIGHT, 5);
  396.     sizerRow->Add(m_textAdd, 1, wxLEFT, 5);
  397.     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
  398.  
  399.     btn = new wxButton(panel, LboxTest_AddSeveral, _T("&Insert a few strings"));
  400.     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  401.  
  402.     btn = new wxButton(panel, LboxTest_AddMany, _T("Add &many strings"));
  403.     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  404.  
  405.     sizerRow = new wxBoxSizer(wxHORIZONTAL);
  406.     btn = new wxButton(panel, LboxTest_Change, _T("C&hange current"));
  407.     m_textChange = new wxTextCtrl(panel, LboxTest_ChangeText, _T(""));
  408.     sizerRow->Add(btn, 0, wxRIGHT, 5);
  409.     sizerRow->Add(m_textChange, 1, wxLEFT, 5);
  410.     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
  411.  
  412.     sizerRow = new wxBoxSizer(wxHORIZONTAL);
  413.     btn = new wxButton(panel, LboxTest_Delete, _T("&Delete this item"));
  414.     m_textDelete = new wxTextCtrl(panel, LboxTest_DeleteText, _T(""));
  415.     sizerRow->Add(btn, 0, wxRIGHT, 5);
  416.     sizerRow->Add(m_textDelete, 1, wxLEFT, 5);
  417.     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
  418.  
  419.     btn = new wxButton(panel, LboxTest_DeleteSel, _T("Delete &selection"));
  420.     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  421.  
  422.     btn = new wxButton(panel, LboxTest_Clear, _T("&Clear"));
  423.     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
  424.  
  425.     // right pane
  426.     m_lbox = new wxListBox(panel, LboxTest_Listbox,
  427.                            wxDefaultPosition, wxDefaultSize,
  428.                            0, NULL,
  429.                            wxLB_HSCROLL);
  430.     sizerRight->Add(m_lbox, 1, wxGROW | wxALL, 5);
  431.     sizerRight->SetMinSize(250, 0);
  432.     m_sizerLbox = sizerRight; // save it to modify it later
  433.  
  434.     // the 3 panes panes compose the upper part of the window
  435.     sizerUp->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
  436.     sizerUp->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
  437.     sizerUp->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
  438.  
  439.     // the lower one only has the log listbox and a button to clear it
  440.     wxSizer *sizerDown = new wxStaticBoxSizer
  441.                              (
  442.                                new wxStaticBox(panel, -1, _T("&Log window")),
  443.                                wxVERTICAL
  444.                              );
  445.     m_lboxLog = new wxListBox(panel, -1);
  446.     sizerDown->Add(m_lboxLog, 1, wxGROW | wxALL, 5);
  447.     wxBoxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
  448.     btn = new wxButton(panel, LboxTest_ClearLog, _T("Clear &log"));
  449.     sizerBtns->Add(btn);
  450.     sizerBtns->Add(10, 0); // spacer
  451.     btn = new wxButton(panel, LboxTest_Quit, _T("E&xit"));
  452.     sizerBtns->Add(btn);
  453.     sizerDown->Add(sizerBtns, 0, wxALL | wxALIGN_RIGHT, 5);
  454.  
  455.     // put everything together
  456.     sizerTop->Add(sizerUp, 1, wxGROW | (wxALL & ~wxBOTTOM), 10);
  457.     sizerTop->Add(0, 5, 0, wxGROW); // spacer in between
  458.     sizerTop->Add(sizerDown, 0,  wxGROW | (wxALL & ~wxTOP), 10);
  459.  
  460.     // final initialization
  461.     Reset();
  462.     m_dirty = FALSE;
  463.  
  464.     panel->SetAutoLayout(TRUE);
  465.     panel->SetSizer(sizerTop);
  466.  
  467.     sizerTop->Fit(this);
  468.     sizerTop->SetSizeHints(this);
  469.  
  470.     // now that everything is created we can redirect the log messages to the
  471.     // listbox
  472.     m_logTarget = new LboxLogger(m_lboxLog, wxLog::GetActiveTarget());
  473.     wxLog::SetActiveTarget(m_logTarget);
  474. }
  475.  
  476. LboxTestFrame::~LboxTestFrame()
  477. {
  478.     delete m_logTarget;
  479. }
  480.  
  481. // ----------------------------------------------------------------------------
  482. // operations
  483. // ----------------------------------------------------------------------------
  484.  
  485. void LboxTestFrame::Reset()
  486. {
  487.     if ( m_radioSelMode->GetSelection() == LboxSel_Single &&
  488.          !m_chkSort->GetValue() &&
  489.          m_chkHScroll->GetValue() &&
  490.          !m_chkVScroll->GetValue() )
  491.     {
  492.         // nothing to do
  493.         return;
  494.     }
  495.  
  496.     m_radioSelMode->SetSelection(LboxSel_Single);
  497.     m_chkSort->SetValue(FALSE);
  498.     m_chkHScroll->SetValue(TRUE);
  499.     m_chkVScroll->SetValue(FALSE);
  500.  
  501.     m_dirty = TRUE;
  502. }
  503.  
  504. void LboxTestFrame::CreateLbox()
  505. {
  506.     int flags = 0;
  507.     switch ( m_radioSelMode->GetSelection() )
  508.     {
  509.         default:
  510.             wxFAIL_MSG( _T("unexpected radio box selection") );
  511.  
  512.         case LboxSel_Single:    flags |= wxLB_SINGLE; break;
  513.         case LboxSel_Extended:  flags |= wxLB_EXTENDED; break;
  514.         case LboxSel_Multiple:  flags |= wxLB_MULTIPLE; break;
  515.     }
  516.  
  517.     if ( m_chkVScroll->GetValue() )
  518.         flags |= wxLB_ALWAYS_SB;
  519.     if ( m_chkHScroll->GetValue() )
  520.         flags |= wxLB_HSCROLL;
  521.     if ( m_chkSort->GetValue() )
  522.         flags |= wxLB_SORT;
  523.  
  524.     wxArrayString items;
  525.     if ( m_lbox )
  526.     {
  527.         int count = m_lbox->GetCount();
  528.         for ( int n = 0; n < count; n++ )
  529.         {
  530.             items.Add(m_lbox->GetString(n));
  531.         }
  532.  
  533.         m_sizerLbox->Remove(m_lbox);
  534.         delete m_lbox;
  535.     }
  536.  
  537.     m_lbox = new wxListBox(this, -1,
  538.                            wxDefaultPosition, wxDefaultSize,
  539.                            0, NULL,
  540.                            flags);
  541.     m_lbox->Set(items);
  542.     m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5);
  543.     m_sizerLbox->Layout();
  544.  
  545.     m_dirty = FALSE;
  546. }
  547.  
  548. // ----------------------------------------------------------------------------
  549. // event handlers
  550. // ----------------------------------------------------------------------------
  551.  
  552. void LboxTestFrame::OnButtonQuit(wxCommandEvent& WXUNUSED(event))
  553. {
  554.     Close();
  555. }
  556.  
  557. void LboxTestFrame::OnButtonReset(wxCommandEvent& WXUNUSED(event))
  558. {
  559.     Reset();
  560. }
  561.  
  562. void LboxTestFrame::OnButtonCreate(wxCommandEvent& WXUNUSED(event))
  563. {
  564.     CreateLbox();
  565. }
  566.  
  567. void LboxTestFrame::OnButtonChange(wxCommandEvent& WXUNUSED(event))
  568. {
  569.     wxArrayInt selections;
  570.     int count = m_lbox->GetSelections(selections);
  571.     wxString s = m_textChange->GetValue();
  572.     for ( int n = 0; n < count; n++ )
  573.     {
  574.         m_lbox->SetString(selections[n], s);
  575.     }
  576. }
  577.  
  578. void LboxTestFrame::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
  579. {
  580.     unsigned long n;
  581.     if ( !m_textDelete->GetValue().ToULong(&n) ||
  582.             (n >= (unsigned)m_lbox->GetCount()) )
  583.     {
  584.         return;
  585.     }
  586.  
  587.     m_lbox->Delete(n);
  588. }
  589.  
  590. void LboxTestFrame::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
  591. {
  592.     wxArrayInt selections;
  593.     int n = m_lbox->GetSelections(selections);
  594.     while ( n > 0 )
  595.     {
  596.         m_lbox->Delete(selections[--n]);
  597.     }
  598. }
  599.  
  600. void LboxTestFrame::OnButtonClear(wxCommandEvent& event)
  601. {
  602.     m_lbox->Clear();
  603. }
  604.  
  605. void LboxTestFrame::OnButtonClearLog(wxCommandEvent& event)
  606. {
  607.     m_lboxLog->Clear();
  608. }
  609.  
  610. void LboxTestFrame::OnButtonAdd(wxCommandEvent& event)
  611. {
  612.     static size_t s_item = 0;
  613.  
  614.     wxString s = m_textAdd->GetValue();
  615.     if ( !m_textAdd->IsModified() )
  616.     {
  617.         // update the default string
  618.         m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
  619.     }
  620.  
  621.     m_lbox->Append(s);
  622. }
  623.  
  624. void LboxTestFrame::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
  625. {
  626.     // "many" means 1000 here
  627.     for ( size_t n = 0; n < 1000; n++ )
  628.     {
  629.         m_lbox->Append(wxString::Format(_T("item #%u"), n));
  630.     }
  631. }
  632.  
  633. void LboxTestFrame::OnButtonAddSeveral(wxCommandEvent& event)
  634. {
  635.     wxArrayString items;
  636.     items.Add(_T("First"));
  637.     items.Add(_T("another one"));
  638.     items.Add(_T("and the last (very very very very very very very very very very long) one"));
  639.     m_lbox->InsertItems(items, 0);
  640. }
  641.  
  642. void LboxTestFrame::OnUpdateUICreateButton(wxUpdateUIEvent& event)
  643. {
  644.     event.Enable(m_dirty);
  645. }
  646.  
  647. void LboxTestFrame::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
  648. {
  649.     unsigned long n;
  650.     event.Enable(m_textDelete->GetValue().ToULong(&n) &&
  651.                     (n < (unsigned)m_lbox->GetCount()));
  652. }
  653.  
  654. void LboxTestFrame::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
  655. {
  656.     wxArrayInt selections;
  657.     event.Enable(m_lbox->GetSelections(selections) != 0);
  658. }
  659.  
  660. void LboxTestFrame::OnUpdateUIClearButton(wxUpdateUIEvent& event)
  661. {
  662.     event.Enable(m_lbox->GetCount() != 0);
  663. }
  664.  
  665. void LboxTestFrame::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
  666. {
  667.     event.Enable(!(m_lbox->GetWindowStyle() & wxLB_SORT));
  668. }
  669.  
  670. void LboxTestFrame::OnListbox(wxCommandEvent& event)
  671. {
  672.     int sel = event.GetInt();
  673.     m_textDelete->SetValue(wxString::Format(_T("%ld"), sel));
  674.  
  675.     wxLogMessage(_T("Listbox item %d selected"), sel);
  676. }
  677.  
  678. void LboxTestFrame::OnListboxDClick(wxCommandEvent& event)
  679. {
  680.     wxLogMessage(_T("Listbox item %d double clicked"), event.GetInt());
  681. }
  682.  
  683. void LboxTestFrame::OnCheckOrRadioBox(wxCommandEvent& event)
  684. {
  685.     m_dirty = TRUE;
  686. }
  687.  
  688.