home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / COMBOBOX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  7.9 KB  |  327 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   source\owl\combobox.cpp
  4. //   Implementation of TComboBox & TComboBoxData.
  5. //----------------------------------------------------------------------------
  6. #pragma hdrignore SECTION
  7. #include <owl\owlpch.h>
  8. #include <owl\combobox.h>
  9. #include <cstring.h>
  10.  
  11. #if !defined(SECTION) || SECTION == 1
  12.  
  13. //
  14. // constructor for a TComboBoxData object
  15. //
  16. TComboBoxData::TComboBoxData()
  17.  : Strings(10, 0, 10),
  18.    ItemDatas(10, 0, 10)
  19. {
  20.   SelIndex = 0;
  21. }
  22.  
  23. //
  24. // destructor for TComboBoxData
  25. //
  26. TComboBoxData::~TComboBoxData()
  27. {
  28. }
  29.  
  30. //
  31. // adds the supplied string to the "Strings" array and copies it into
  32. // "Selection" if "isSelected" is TRUE
  33. //
  34. void
  35. TComboBoxData::AddString(const char* str, BOOL isSelected)
  36. {
  37.   Strings.Add(str);
  38.   if (isSelected)
  39.     Select(Strings.GetItemsInContainer()-1);
  40. }
  41.  
  42. void
  43. TComboBoxData::AddStringItem(const char* str, DWORD itemData, BOOL isSelected)
  44. {
  45.   ItemDatas.Add(itemData);
  46.   AddString(str, isSelected);
  47. }
  48.  
  49. //
  50. // selects an item at a given index.
  51. //
  52. void
  53. TComboBoxData::Select(int index)
  54. {
  55.   if (index != CB_ERR) {
  56.     SelIndex = index;
  57.     if (index < Strings.GetItemsInContainer())
  58.       Selection = Strings[index];
  59.   }
  60. }
  61.  
  62. //
  63. // selects "str", marking the matching String entry (if any) as selected
  64. //
  65. void
  66. TComboBoxData::SelectString(const char far* str)
  67. {
  68.   int numStrings = Strings.GetItemsInContainer();
  69.   SelIndex = CB_ERR;
  70.   for (int i = 0; i < numStrings; i++)
  71.     if (strcmp(Strings[i].c_str(), str) == 0) {
  72.       SelIndex = i;
  73.       break;
  74.     }
  75.   if (Selection != str)
  76.     Selection = str;
  77. }
  78.  
  79. //
  80. // returns the length of the selection string excluding the terminating 0
  81. //
  82. int
  83. TComboBoxData::GetSelStringLength() const
  84. {
  85.   return Selection.length();
  86. }
  87.  
  88. //
  89. // copies the selected string into Buffer. BufferSize includes the terminating 0
  90. //
  91. void
  92. TComboBoxData::GetSelString(char far* buffer, int bufferSize) const
  93. {
  94.   if (bufferSize > 0) {
  95.     strncpy(buffer, Selection.c_str(), bufferSize-1);
  96.     buffer[bufferSize - 1] = 0;
  97.   }
  98. }
  99.  
  100. //----------------------------------------------------------------------------
  101.  
  102. //
  103. // constructor for a TComboBox object
  104. //
  105. // by default, an MS-Windows combobox associated with the TComboBox will have
  106. // a vertical scrollbar and will maintain its entries in alphabetical order
  107. //
  108. TComboBox::TComboBox(TWindow*        parent,
  109.                      int             id,
  110.                      int x, int y, int w, int h,
  111.                      DWORD           style,
  112.                      UINT            textLen,
  113.                      TModule*        module)
  114.   : TListBox(parent, id, x, y, w, h, module)
  115. {
  116.   TextLen = textLen;
  117.   Attr.Style = WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP |
  118.                CBS_SORT | CBS_AUTOHSCROLL | WS_VSCROLL | style;
  119. }
  120.  
  121. TComboBox::TComboBox(TWindow*   parent,
  122.                      int        resourceId,
  123.                      UINT       textLen,
  124.                      TModule*   module)
  125.   : TListBox(parent, resourceId, module)
  126. {
  127.   TextLen = textLen;
  128. }
  129.  
  130. //
  131. // sets and selects the contents of the associated edit control to the
  132. // supplied string
  133. //
  134. void
  135. TComboBox::SetText(const char far* str)
  136. {
  137.   //
  138.   // if str is 0, then use empty str
  139.   //
  140.   if (!str)
  141.     str = "";
  142.  
  143.   //
  144.   // if not in listbox, then set the edit/static portion
  145.   //
  146.   if (SetSelString(str, -1) < 0) {
  147.     SetWindowText(str);
  148.     SetEditSel(0, strlen(str));
  149.   }
  150. }
  151.  
  152. //
  153. // returns, in the supplied reference parameters, the starting and
  154. // ending positions of the text selected in the associated edit control
  155. //
  156. // returns CB_ERR is the combo box has no edit control
  157. //
  158. int
  159. TComboBox::GetEditSel(int& startPos, int& endPos)
  160. {
  161.   LRESULT  retValue = HandleMessage(CB_GETEDITSEL);
  162.  
  163.   startPos = LOWORD(retValue);
  164.   endPos   = HIWORD(retValue);
  165.  
  166.   return (int)retValue;
  167. }
  168.  
  169. //
  170. // shows or hides the drop-down list
  171. //
  172. void
  173. TComboBox::ShowList(BOOL show)
  174. {
  175.   if ((GetWindowLong(GWL_STYLE) & CBS_DROPDOWN) == CBS_DROPDOWN)
  176.     HandleMessage(CB_SHOWDROPDOWN, show);
  177. }
  178.  
  179. static void
  180. DoAddStringToCB(string& str, void* comboBox)
  181. {
  182.   ((TListBox*)comboBox)->AddString(str.c_str());
  183. }
  184.  
  185. //
  186. // transfers the items and selection of the combo box to or from a transfer
  187. // buffer if tdSetData or tdGetData, respectively, is passed as the
  188. // direction
  189. //
  190. // buffer should point to a TComboBoxData which points to the data to be
  191. // transferred
  192. //
  193. // Transfer returns the size of TComboBoxData
  194. //
  195. // to retrieve the size without transferring data, pass tdSizeData as the
  196. // direction
  197. //
  198. UINT
  199. TComboBox::Transfer(void* buffer, TTransferDirection direction)
  200. {
  201.   TComboBoxData* comboBoxData = (TComboBoxData*)buffer;
  202.  
  203.   if (direction == tdGetData) {
  204.     //
  205.     // Clear out Strings array and fill with contents of list box part
  206.     // Prescan for longest string to allow a single temp allocation
  207.     //
  208.     comboBoxData->Clear();
  209.  
  210.     int  count = GetCount();
  211.     int  maxStringLen = 0;
  212.     for (int i = 0; i < count; i++) {
  213.       int  stringLen = GetStringLen(i);
  214.       if (stringLen > maxStringLen)
  215.         maxStringLen = stringLen;
  216.     }
  217.     char*  tmpString = new char[maxStringLen+1];
  218.     for (i = 0; i < count; i++) {
  219.       GetString(tmpString, i);
  220.       comboBoxData->AddString(tmpString, FALSE);
  221.       comboBoxData->GetItemDatas()[i] = GetItemData(i);
  222.     }
  223.     delete tmpString;
  224.  
  225.     //
  226.     // Get the sel string from the list by index, or if no index from the
  227.     // edit box
  228.     //
  229.     int selIndex = GetSelIndex();
  230.     if (selIndex >= 0) {
  231.       int  stringLen = GetStringLen(selIndex);
  232.       if (stringLen > 0) {
  233.         char* str = new char[stringLen+1];
  234.         GetString(str, selIndex);
  235.         comboBoxData->SelectString(str);
  236.         delete str;
  237.       
  238.       } else
  239.         comboBoxData->SelectString("");
  240.  
  241.     } else {
  242.       int  stringLen = GetWindowTextLength();
  243.       if (stringLen > 0) {
  244.         char* str = new char[stringLen+1];
  245.         GetWindowText(str, stringLen+1);
  246.         comboBoxData->SelectString(str);
  247.         delete str;
  248.  
  249.       } else
  250.         comboBoxData->SelectString("");
  251.     }
  252.  
  253.   } else if (direction == tdSetData) {
  254.     ClearList();
  255.     comboBoxData->GetStrings().ForEach(DoAddStringToCB, this);
  256.     for (int i = 0; i < comboBoxData->GetItemDatas().GetItemsInContainer(); i++)
  257.       SetItemData(i, comboBoxData->GetItemDatas()[i]);
  258.  
  259.     SetWindowText(comboBoxData->GetSelection().c_str());
  260.     if (comboBoxData->GetSelIndex() >= 0)
  261.       SetSelIndex(comboBoxData->GetSelIndex());
  262.   }
  263.  
  264.   return sizeof(TComboBoxData);
  265. }
  266.  
  267. //
  268. // Return name of predefined Windows combobox class
  269. //
  270. char far*
  271. TComboBox::GetClassName()
  272. {
  273.   return "COMBOBOX";
  274. }
  275.  
  276. //
  277. // limits the amount of text that the user can enter in the combo box's
  278. // edit control to the value of TextLen minus 1
  279. //
  280. // creates aliases for the children in the combo box so that TWindow can
  281. // handle kill focus messages for focus support.
  282. //
  283. void
  284. TComboBox::SetupWindow()
  285. {
  286.   TListBox::SetupWindow();
  287.  
  288.   if (TextLen != 0)
  289.     HandleMessage(CB_LIMITTEXT, TextLen-1);
  290.  
  291.   HWND hWnd = ::GetWindow(HWindow, GW_CHILD);
  292.   while (hWnd) {
  293.     if (!GetWindowPtr(hWnd))
  294.       new TWindow(hWnd);
  295.     hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  296.   }
  297. }
  298.  
  299. #endif
  300. #if !defined(SECTION) || SECTION == 2
  301.  
  302. IMPLEMENT_STREAMABLE1(TComboBox, TListBox);
  303.  
  304. //
  305. // reads an instance of TComboBox from the supplied ipstream
  306. //
  307. void*
  308. TComboBox::Streamer::Read(ipstream& is, uint32 /*version*/) const
  309. {
  310.   ReadBaseObject((TListBox*)GetObject(), is);
  311.   is >> GetObject()->TextLen;
  312.   return GetObject();
  313. }
  314.  
  315. //
  316. // writes the TComboBox to the supplied opstream
  317. //
  318. void
  319. TComboBox::Streamer::Write(opstream& os) const
  320. {
  321.   WriteBaseObject((TListBox*)GetObject(), os);
  322.   os << GetObject()->TextLen;
  323. }
  324.  
  325. #endif
  326.  
  327.