home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / LISTBOX.PAK / LISTBOXX.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  16KB  |  570 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //----------------------------------------------------------------------------
  4. #include <owl\owlpch.h>
  5. #include <owl\applicat.h>
  6. #include <owl\framewin.h>
  7. #include <owl\static.h>
  8. #include <owl\listbox.h>
  9. #include <owl\inputdia.h>
  10. #include <owl\validate.h>
  11. #include <string.h>
  12. #include "listboxx.rh"
  13.  
  14. // List box ids.
  15.  
  16. const WORD ID_LB_BASE               = 200;
  17. const WORD ID_STANDARD              = ID_LB_BASE;
  18. const WORD ID_MULTI_SEL             = ID_LB_BASE + 1;
  19. const WORD ID_MULTI_COLUMN          = ID_LB_BASE + 2;
  20.  
  21. class TListBoxWindow : public TFrameWindow {
  22.   public:
  23.     TListBoxWindow(const char* title);
  24.  
  25.     // message response functions
  26.     //
  27.  
  28.     void EvLBNSelChange();
  29.  
  30.     void CmStandard();               // create standard list box.
  31.     void CmMultiSel();               // create multi-select list box.
  32.     void CmMultiColumn();            // create multi-column list box.
  33.     void CmAddString();              // add string to list box.
  34.     void CmAddStringAt();            // add string at index position.
  35.     void CmFindString();             // goto index of given string, display string.
  36.     void CmFindStringAt();           // goto index, display string.
  37.     void CmDeleteString();           // delete string.
  38.     void CmDeleteStringAt();         // delete string at index.
  39.     void CmClear();                  // clear ListBox.
  40.     void CmDirList();                // show directory list.
  41.  
  42.     // Command enablers.
  43.     //
  44.     void CmEnableStandard(TCommandEnabler& commandHandler);
  45.     void CmEnableMultiSel(TCommandEnabler& commandHandler);
  46.     void CmEnableMultiColumn(TCommandEnabler& commandHandler);
  47.     void CmEnableOther(TCommandEnabler& commandHandler);
  48.  
  49.   private:
  50.     TListBox*         ListBox;                 // list box.
  51.     TStatic*          CurSelOfListBox;         // text of selected string.
  52.     TStatic*          CurSelIndexOfListBox;    // index of selected string.
  53.     TStatic*          SelStringLength;         // length of selected string.
  54.     TStatic*          ItemCount;               // number of items in list box.
  55.     TStatic*          TopIndex;                // index of first visible item.
  56.     TStatic*          SelCount;                // # of selected items.
  57.     TStatic*          SelStrings;              // first 3 selected strings.
  58.     TStatic*          SelIndexes;              // first 3 indexes.
  59.  
  60.     WORD              WhichListBox;            // current ListBox.
  61.  
  62.     static const int  TextLen;                 // length of input text.
  63.  
  64.     void  ResetTextFields();                   // reset text fields to blanks.
  65.     void  UpdateTextFields();                  // updates from list box.
  66.     int   InputString(char* pmpt, char* s);    // get string from user.
  67.     int   InputNumber(char* pmpt, char* s);    // get number from user.
  68.                                                // get string and number.
  69.     int   InputStringAndNumber(char* pmpt, char* s, int& n);
  70.  
  71.   DECLARE_RESPONSE_TABLE(TListBoxWindow);
  72. };
  73.  
  74. DEFINE_RESPONSE_TABLE1(TListBoxWindow, TFrameWindow)
  75.   EV_WM_INITMENUPOPUP,
  76.   EV_LBN_SELCHANGE(ID_STANDARD,     EvLBNSelChange),
  77.   EV_LBN_SELCHANGE(ID_MULTI_SEL,    EvLBNSelChange),
  78.   EV_LBN_SELCHANGE(ID_MULTI_COLUMN, EvLBNSelChange),
  79.   EV_COMMAND(CM_STANDARD,           CmStandard),
  80.   EV_COMMAND(CM_MULTI_SEL,          CmMultiSel),
  81.   EV_COMMAND(CM_MULTI_COLUMN,       CmMultiColumn),
  82.   EV_COMMAND(CM_ADD_STRING,         CmAddString),
  83.   EV_COMMAND(CM_ADD_STRING_AT,      CmAddStringAt),
  84.   EV_COMMAND(CM_FIND_STRING,        CmFindString),
  85.   EV_COMMAND(CM_FIND_STRING_AT,     CmFindStringAt),
  86.   EV_COMMAND(CM_DELETE_STRING,      CmDeleteString),
  87.   EV_COMMAND(CM_DELETE_STRING_AT,   CmDeleteStringAt),
  88.   EV_COMMAND(CM_CLEAR,              CmClear),
  89.   EV_COMMAND(CM_DIR_LIST,           CmDirList),
  90.  
  91.   EV_COMMAND_ENABLE(CM_STANDARD,         CmEnableStandard),
  92.   EV_COMMAND_ENABLE(CM_MULTI_SEL,        CmEnableMultiSel),
  93.   EV_COMMAND_ENABLE(CM_MULTI_COLUMN,     CmEnableMultiColumn),
  94.   EV_COMMAND_ENABLE(CM_ADD_STRING,       CmEnableOther),
  95.   EV_COMMAND_ENABLE(CM_ADD_STRING_AT,    CmEnableOther),
  96.   EV_COMMAND_ENABLE(CM_FIND_STRING,      CmEnableOther),
  97.   EV_COMMAND_ENABLE(CM_FIND_STRING_AT,   CmEnableOther),
  98.   EV_COMMAND_ENABLE(CM_DELETE_STRING,    CmEnableOther),
  99.   EV_COMMAND_ENABLE(CM_DELETE_STRING_AT, CmEnableOther),
  100.   EV_COMMAND_ENABLE(CM_CLEAR,            CmEnableOther),
  101.   EV_COMMAND_ENABLE(CM_DIR_LIST,         CmEnableOther),
  102. END_RESPONSE_TABLE;
  103.  
  104. const int TListBoxWindow::TextLen = 21;
  105.  
  106. //
  107. // Constructor.  Setup menu and text areas.
  108. //
  109. TListBoxWindow::TListBoxWindow(const char* title)
  110.   : TFrameWindow(0, title)
  111. {
  112.   ListBox = 0;
  113.   WhichListBox = 0;
  114.   AssignMenu("LISTBOX_MENU");
  115.  
  116.   // setup static text areas.
  117.   //
  118.   new TStatic(this, -1, "Current selection:",  200, 30, 122, 18, 18);
  119.   CurSelOfListBox = new TStatic(this, -1, " ",  392, 30, 158, 18, 25);
  120.  
  121.   new TStatic(this, -1, "Index of current selection:",  200, 52, 176, 18, 18);
  122.   CurSelIndexOfListBox = new TStatic(this, -1, " ",  392, 52, 158, 18, 25);
  123.  
  124.   new TStatic(this, -1, "Length of current selection:",  200, 76, 184, 18, 18);
  125.   SelStringLength = new TStatic(this, -1, " ",  392, 76, 158, 18, 25);
  126.  
  127.   new TStatic(this, -1, "Number of items:",  200, 98, 184, 18, 18);
  128.   ItemCount = new TStatic(this, -1, " ",  392, 98, 158, 18, 25);
  129.  
  130.   new TStatic(this, -1, "First visible item:",  200, 120, 184, 18, 18);
  131.   TopIndex = new TStatic(this, -1, " ",  392, 120, 158, 18, 25);
  132.  
  133.   new TStatic(this, -1, "<Multi-Select only>",  200, 142, 184, 18, 25);
  134.  
  135.   new TStatic(this, -1, "Number of selected items:",  200, 164, 184, 18, 25);
  136.   SelCount = new TStatic(this, -1, " ",  392, 164, 158, 18, 25);
  137.  
  138.   new TStatic(this, -1, "First 3 selected strings:",  200, 186, 184, 18, 25);
  139.   SelStrings = new TStatic(this, -1, " ",  392, 186, 158, 18, 35);
  140.  
  141.   new TStatic(this, -1, "Indexes of first 3 selected strings:",  200, 208,
  142.               200, 18, 25);
  143.   SelIndexes = new TStatic(this, -1, " ",  392, 208, 158, 18, 25);
  144. }
  145.  
  146. //
  147. // A selection has taken place, update text info.
  148. //
  149. void
  150. TListBoxWindow::EvLBNSelChange()
  151. {
  152.   UpdateTextFields();
  153. }
  154.  
  155. //
  156. // 'ListBox|Standard' menu item.  Create simple list box and fill it with some
  157. // strings.
  158. //
  159. void
  160. TListBoxWindow::CmStandard()
  161. {
  162.   if (ListBox) {
  163.     ListBox->Destroy();
  164.     delete ListBox;
  165.   }
  166.   ListBox = new TListBox(this, ID_STANDARD, 10, 30, 150, 150);
  167.   ListBox->Attr.Style;
  168.   ListBox->Create();
  169.   ListBox->SetFocus();
  170.   ListBox->AddString("dog");
  171.   ListBox->AddString("bird");
  172.   ListBox->AddString("mouse");
  173.   ListBox->AddString("car");
  174.  
  175.   WhichListBox = ID_STANDARD;
  176.  
  177.   ResetTextFields();
  178.   UpdateTextFields();
  179. }
  180.  
  181. //
  182. // 'ListBox|Multi-Select' menu item.  Create multi-select list box and fill it
  183. // with some strings.
  184. //
  185. void
  186. TListBoxWindow::CmMultiSel()
  187. {
  188.   if (ListBox) {
  189.     ListBox->Destroy();
  190.     delete ListBox;
  191.   }
  192.   ListBox = new TListBox(this, ID_MULTI_SEL, 10, 30, 150, 150);
  193.   ListBox->Attr.Style |= LBS_MULTIPLESEL;
  194.   ListBox->Create();
  195.   ListBox->SetFocus();
  196.   ListBox->AddString("string1");
  197.   ListBox->AddString("Hello!");
  198.   ListBox->AddString("Box");
  199.  
  200.   WhichListBox = ID_MULTI_SEL;
  201.  
  202.   ResetTextFields();
  203.   UpdateTextFields();
  204. }
  205.  
  206. //
  207. // 'ListBox|Multi-Column' menu item.  Create multi-column list box and fill
  208. // it with some strings.
  209. //
  210. void
  211. TListBoxWindow::CmMultiColumn()
  212. {
  213.   if (ListBox) {
  214.     ListBox->Destroy();
  215.     delete ListBox;
  216.   }
  217.   ListBox = new TListBox(this, ID_MULTI_COLUMN, 10, 30, 150, 150);
  218.   ListBox->Attr.Style |= LBS_MULTICOLUMN;
  219.   ListBox->Attr.Style &= ~LBS_SORT;
  220.   ListBox->Create();
  221.   ListBox->SetFocus();
  222.   ListBox->SetColumnWidth(100);   // about half of the list box window.
  223.   ListBox->AddString("Have");
  224.   ListBox->AddString("a");
  225.   ListBox->AddString("nice");
  226.   ListBox->AddString("Day");
  227.   ListBox->AddString("blue");
  228.   ListBox->AddString("green");
  229.   ListBox->AddString("yellow");
  230.   ListBox->AddString("gold");
  231.   ListBox->AddString("red");
  232.   ListBox->AddString("black");
  233.   ListBox->AddString("white");
  234.   ListBox->AddString("grey");
  235.  
  236.   WhichListBox = ID_MULTI_COLUMN;
  237.  
  238.   ResetTextFields();
  239.   UpdateTextFields();
  240. }
  241.  
  242. //
  243. // Add a string to the list box.
  244. //
  245. void
  246. TListBoxWindow::CmAddString()
  247. {
  248.   char  buf[TextLen] = "";
  249.  
  250.   if (InputString("Enter string:", buf)) {
  251.     ListBox->AddString(buf);
  252.     UpdateTextFields();
  253.   }
  254. }
  255.  
  256. //
  257. // Insert a string at a given index of the listbox.
  258. //
  259. void
  260. TListBoxWindow::CmAddStringAt()
  261. {
  262.   char  buf[TextLen] = "";
  263.   int   index;
  264.  
  265.   if (InputStringAndNumber("Enter string:", buf, index)) {
  266.     if (ListBox->InsertString(buf, index) != LB_ERR)
  267.       UpdateTextFields();
  268.     else
  269.       MessageBox("Index out of range", "Error", MB_OK);
  270.   }
  271. }
  272.  
  273. //
  274. // Find string.  Tell list box to select string at given index.
  275. // Update text fields.
  276. //
  277. void
  278. TListBoxWindow::CmFindString()
  279. {
  280.   char  buf[TextLen] = "";
  281.   int   index;
  282.  
  283.   if (InputString( "Enter string:", buf)) {
  284.     if ((index = ListBox->FindString(buf, -1)) != LB_ERR) {
  285.       if (WhichListBox == ID_MULTI_SEL)
  286.         ListBox->SetSel(index, TRUE);
  287.       else
  288.         ListBox->HandleMessage(LB_SETCURSEL, index, 0);
  289.       UpdateTextFields();
  290.  
  291.     } else
  292.       MessageBox("String not found", "Error", MB_OK);
  293.   }
  294. }
  295.  
  296. //
  297. // Find string.  Tell list box to select string at given index.
  298. // Update text fields.  Assumes index input is correct, else atoi()
  299. // will return 0 and will be used to select the first string.
  300. //
  301. void
  302. TListBoxWindow::CmFindStringAt()
  303. {
  304.   char  buf[TextLen] = "";
  305.   int   index;
  306.  
  307.   if (InputNumber("Enter number:", buf)) {
  308.     index = atoi(buf);
  309.     if (ListBox->GetString(buf, index) != LB_ERR) {
  310.       if (WhichListBox == ID_MULTI_SEL)
  311.         ListBox->SetSel(index, TRUE);
  312.       else
  313.         ListBox->HandleMessage(LB_SETCURSEL, index, 0);
  314.       UpdateTextFields();
  315.  
  316.     } else
  317.       MessageBox("Index out of range", "Error", MB_OK);
  318.   }
  319. }
  320.  
  321. //
  322. // Delete string.  Delete string input by user.
  323. //
  324. void
  325. TListBoxWindow::CmDeleteString()
  326. {
  327.   char  buf[TextLen] = "";
  328.  
  329.   if (InputString("Enter string:", buf)) {
  330.     int  index;
  331.     if ((index = ListBox->FindString(buf, 0)) != LB_ERR) {
  332.       ListBox->DeleteString(index);
  333.       UpdateTextFields();
  334.  
  335.     } else
  336.       MessageBox("String not found", "Error", MB_OK);
  337.   }
  338. }
  339.  
  340. //
  341. // Delete string.  Delete string at given index.
  342. //
  343. void
  344. TListBoxWindow::CmDeleteStringAt()
  345. {
  346.   char  buf[TextLen] = "";
  347.   int   index;
  348.  
  349.   if (InputNumber("Enter number:", buf)) {
  350.     index = atoi(buf);
  351.     if (ListBox->GetString(buf, index) != LB_ERR) {
  352.       ListBox->DeleteString(index);
  353.       UpdateTextFields();
  354.     }
  355.     else
  356.       MessageBox("Index out of range", "Error", MB_OK);
  357.   }
  358. }
  359.  
  360. //
  361. // Clear.  Clear list box of all strings.
  362. //
  363. void
  364. TListBoxWindow::CmClear()
  365. {
  366.   ListBox->ClearList();
  367.   ResetTextFields();
  368. }
  369.  
  370. //
  371. // Directory list.  Add strings representing the files in the current
  372. // directory.
  373. //
  374. void
  375. TListBoxWindow::CmDirList()
  376. {
  377.   ListBox->DirectoryList(0, "*.*");    // all normal files.
  378.   UpdateTextFields();
  379. }
  380.  
  381. //
  382. // Command Enablers.
  383. //
  384.  
  385. void
  386. TListBoxWindow::CmEnableStandard(TCommandEnabler& commandHandler)
  387. {
  388.   commandHandler.Enable(WhichListBox != ID_STANDARD ||
  389.                         !ListBox);
  390. }
  391.  
  392. void
  393. TListBoxWindow::CmEnableMultiSel(TCommandEnabler& commandHandler)
  394. {
  395.   commandHandler.Enable(WhichListBox != ID_MULTI_SEL ||
  396.                         !ListBox);
  397. }
  398.  
  399. void
  400. TListBoxWindow::CmEnableMultiColumn(TCommandEnabler& commandHandler)
  401. {
  402.   commandHandler.Enable(WhichListBox != ID_MULTI_COLUMN ||
  403.                         !ListBox);
  404. }
  405.  
  406. void
  407. TListBoxWindow::CmEnableOther(TCommandEnabler& commandHandler)
  408. {
  409.   commandHandler.Enable(ListBox != 0);
  410. }
  411.  
  412.  
  413. //
  414. // Updates text fields that reflex the list box's state.
  415. //
  416. void
  417. TListBoxWindow::UpdateTextFields()
  418. {
  419.   char  buf[3*(TextLen+1)] = "";                  // temporary buffers.
  420.   char  buf2[3*(TextLen+1)] = "";
  421.   int   index = ListBox->GetSelIndex();       // Current selection.
  422.   int   strLen;                               // length of string in list box.
  423.   int   multiSelCnt = ListBox->GetSelCount(); // # of selections.
  424.  
  425.   if (index != LB_ERR || multiSelCnt) {  // is something selected?
  426.     if (WhichListBox == ID_MULTI_SEL) {
  427.       char far* strs[3];
  428.       int  indexes[3];
  429.  
  430.       // display number of strings selected.
  431.       //
  432.       itoa(multiSelCnt, buf, 10);
  433.       SelCount->SetText(buf);
  434.  
  435.       // display first 3 selected strings.
  436.       //
  437.       strs[0] = new char[TextLen+1];
  438.       strs[0][0] = 0;
  439.       strs[1] = new char[TextLen+1];
  440.       strs[1][0] = 0;
  441.       strs[2] = new char[TextLen+1];
  442.       strs[2][0] = 0;
  443.       ListBox->GetSelStrings(strs, 3, TextLen);
  444.       strcpy(buf, strs[0]);
  445.       strcat(buf, "  ");
  446.       strcat(strcat(strcat(buf, strs[1]), "  "), strs[2]);
  447.       SelStrings->SetText(buf);
  448.  
  449.       // display indexes of first 3 selected strings.
  450.       //
  451.       int count = ListBox->GetSelIndexes(indexes, 3);
  452.       if (count != LB_ERR) {
  453.         for (int i = 0; i < count; i++) {
  454.           itoa(indexes[i], buf, 10);
  455.           strcat(strcat(buf2, buf), "  ");
  456.         }
  457.         SelIndexes->SetText( buf2 );
  458.       }
  459.       delete strs[0];
  460.       delete strs[1];
  461.       delete strs[2];
  462.     }
  463.     else {
  464.       // display selected string.
  465.       //
  466.       ListBox->GetString(buf, index);
  467.       strLen = ListBox->GetStringLen(index);
  468.       CurSelOfListBox->SetText(buf);
  469.  
  470.       // display length of selected string.
  471.       //
  472.       itoa(strLen, buf, 10);
  473.       SelStringLength->SetText(buf);
  474.  
  475.       // display index of currently selected string.
  476.       //
  477.       itoa(index, buf, 10);
  478.       CurSelIndexOfListBox->SetText(buf);
  479.     }
  480.     // display number of items in list box.
  481.     //
  482.     itoa(ListBox->GetCount(), buf, 10);
  483.     ItemCount->SetText(buf);
  484.  
  485.     // display index of first visible item in list box.
  486.  
  487.     itoa(ListBox->GetTopIndex(), buf, 10);
  488.     TopIndex->SetText(buf);
  489.   }
  490.   else
  491.     ResetTextFields();
  492. }
  493.  
  494. //
  495. // Reset text fields to blanks or default values.
  496. //
  497. void
  498. TListBoxWindow::ResetTextFields()
  499. {
  500.   CurSelOfListBox->SetText(" ");
  501.   SelStringLength->SetText(" ");
  502.   CurSelIndexOfListBox->SetText(" ");
  503.   ItemCount->SetText(" ");
  504.   TopIndex->SetText(" ");
  505.   SelCount->SetText(" ");
  506.   SelStrings->SetText(" ");
  507.   SelIndexes->SetText(" ");
  508. }
  509.  
  510. //
  511. // Get string from user.  Return 1 if successful, 0 otherwise.
  512. // assumes string length of TextLen - 1.
  513. //
  514. int
  515. TListBoxWindow::InputString(char* pmpt, char* s)
  516. {
  517.   return TInputDialog(this, "String", pmpt, s, TextLen - 1).Execute() == IDOK;
  518. }
  519.  
  520. int
  521. TListBoxWindow::InputNumber( char* pmpt, char* s )
  522. {
  523.   return TInputDialog(this, "Number", pmpt, s, TextLen-1, 0,
  524.                       new TFilterValidator("0-9")).Execute() == IDOK;
  525. }
  526.  
  527. //
  528. // Get string and number (index) from user.  Return 1 if successful, 0
  529. // otherwise. Assumes string length of TextLen - 1.
  530. //
  531. int
  532. TListBoxWindow::InputStringAndNumber(char* pmpt, char* s, int& n)
  533. {
  534.   char sbuf[TextLen] = "";
  535.   char nbuf[TextLen] = "";
  536.   TInputDialog getStr(this, "String", pmpt, sbuf, TextLen - 1);
  537.  
  538.   // This input dialog has a validator that only accepts digits
  539.   //
  540.   TInputDialog getNum(this, "String", "Enter number:", nbuf, TextLen-1, 0,
  541.                       new TFilterValidator("0-9"));
  542.  
  543.   if (getStr.Execute() == IDOK &&
  544.       getNum.Execute() == IDOK) {
  545.     strcpy(s, sbuf);
  546.     n = atoi(nbuf);
  547.     return 1;
  548.   } else
  549.     return 0;
  550. }
  551.  
  552. //----------------------------------------------------------------------------
  553.  
  554. class TListBoxApp : public TApplication {
  555.   public:
  556.     void  InitMainWindow();
  557. };
  558.  
  559. void
  560. TListBoxApp::InitMainWindow()
  561. {
  562.   MainWindow = new TListBoxWindow("ListBox Example");
  563. }
  564.  
  565. int
  566. OwlMain(int /*argc*/, char* /*argv*/ [])
  567. {
  568.   return TListBoxApp().Run();
  569. }
  570.