IDCOMBO.CPP
上传用户:zhuqijet
上传日期:2007-01-04
资源大小:138k
文件大小:6k
源码类别:

驱动编程

开发平台:

Visual C++

  1. // IDCombo.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "IDCombo.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CIDCombo
  12. CIDCombo::CIDCombo()
  13. {
  14.  maxlen = 0;  // no limit
  15. }
  16. CIDCombo::~CIDCombo()
  17. {
  18. }
  19. BEGIN_MESSAGE_MAP(CIDCombo, CComboBox)
  20.         //{{AFX_MSG_MAP(CIDCombo)
  21.         ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
  22.         //}}AFX_MSG_MAP
  23. END_MESSAGE_MAP()
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CIDCombo message handlers
  26. /****************************************************************************
  27. *                              CIDCombo::Select
  28. * Inputs:
  29. *       DWORD itemval: ItemData value
  30. * Result: int
  31. *       The index of the selected value, or CB_ERR if no selection possible
  32. * Effect: 
  33. *       If the value exists in the list, selects it, otherwise selects -1
  34. ****************************************************************************/
  35. int CIDCombo::Select(DWORD itemval)
  36.     {
  37.      for(int i = 0; i < GetCount(); i++)
  38.         { /* select */
  39.          DWORD data = GetItemData(i);
  40.          if(itemval == data)
  41.             { /* found it */
  42.              SetCurSel(i);
  43.              return i;
  44.             } /* found it */
  45.         } /* select */
  46.      SetCurSel(-1);
  47.      return CB_ERR;
  48.     }
  49. /****************************************************************************
  50. *                             CIDCombo::AddString
  51. * Inputs:
  52. *       IDData * data: Data to add
  53. * Result: int
  54. *       Index of insertion, or CB_ERR
  55. * Effect: 
  56. *       Adds the string designated by the ID to the combo box, and adds its
  57. *       value to the itemdata
  58. ****************************************************************************/
  59. int CIDCombo::AddString(IDData * data)
  60.     {
  61.      CString s;
  62.      if(s.LoadString(data->id) == 0)
  63.         return CB_ERR;
  64.      int i = CComboBox::AddString(s);
  65.      if(i == CB_ERR)
  66.         return CB_ERR;
  67.      CComboBox::SetItemData(i, data->val);
  68.      return i;
  69.     }
  70. /****************************************************************************
  71. *                            CIDCombo::AddStrings
  72. * Inputs:
  73. *       IDData * data: Pointer to data table
  74. *       int def: ID of default control, or 0 if no default control is to be
  75. *                selected.  
  76. * Result: int
  77. *       index of object selected by 'def'
  78. *       CB_ERR if 'def' object not in list, or error loading, or def == 0
  79. * Effect: 
  80. *       Adds the strings in the table to the combo box.  The table is 
  81. *       terminated by an entry whose id field is 0
  82. * Notes:
  83. *       To select value by itemdata, use the explicit Select operation
  84. ****************************************************************************/
  85. int CIDCombo::AddStrings(IDData * data, int def)
  86.     {
  87.      BOOL found = FALSE;
  88.      CString s;
  89.      for(int i = 0; data[i].id != 0; i++)
  90.         { /* add it */
  91.          int index = AddString(&data[i]);
  92.          if(index == CB_ERR)
  93.            return CB_ERR;
  94.          if(def != 0 && data[i].id == def)
  95.             { /* has selection */
  96.              GetLBText(index, s);
  97.              found = TRUE;
  98.             } /* has selection */
  99.         } /* add it */
  100.      if(found)
  101.         { /* locate selection */
  102.          int index = FindStringExact(-1, s);
  103.          if(index == CB_ERR)
  104.             return CB_ERR;
  105.          return index;
  106.         } /* locate selection */
  107.      return CB_ERR; // no selection matched
  108.     }
  109. /****************************************************************************
  110. *                            CIDCombo::OnDropdown
  111. * Result: void
  112. *       
  113. * Effect: 
  114. *       Sizes the combo to a minimum size required to show everything
  115. * Notes:
  116. *       maxlen determines the maximum length of the combo dropdown
  117. *               0 - no limit, sized so there is no scrollbar
  118. *              >0 - limit to maxlen items, but at least 2
  119. *              -1 - implicitly limit to screen size (NYI)
  120. ****************************************************************************/
  121. void CIDCombo::OnDropdown() 
  122. {
  123.  int n = GetCount();
  124.  n = max(n, 2);
  125.  int ht = GetItemHeight(0);
  126.  CRect r;
  127.  GetWindowRect(&r);
  128.  if(maxlen > 0)
  129.     n = max(maxlen, 2);
  130.  CSize sz;
  131.  sz.cx = r.Width();
  132.  sz.cy = ht * (n + 2);
  133.  if(maxlen < 0)
  134.     { /* screen limit */
  135.      if(r.top - sz.cy < 0 || r.bottom + sz.cy > ::GetSystemMetrics(SM_CYSCREEN))
  136.         { /* invoke limit */
  137.          // Compute the largest distance the dropdown can appear, 
  138.          // relative to the screen (not the window!)
  139.          int k = max( (r.top / ht), 
  140.                       (::GetSystemMetrics(SM_CYSCREEN) - r.bottom) / ht);
  141.          // compute new space. Note that we don't really fill the screen.
  142.          // We only have to use this size if it is smaller than the max size
  143.          // actually required
  144.          int ht2 = ht * k;
  145.          sz.cy = min(ht2, sz.cy);
  146.         } /* invoke limit */
  147.     } /* screen limit */
  148.  SetWindowPos(NULL, 0, 0, sz.cx, sz.cy, SWP_NOMOVE | SWP_NOZORDER);
  149. }
  150. /****************************************************************************
  151. *                            CIDCombo::GetCurItem
  152. * Result: DWORD
  153. *       The itemdata of the current selection, or 0 if there is no selection
  154. ****************************************************************************/
  155. DWORD CIDCombo::GetCurItem()
  156.     {
  157.      int i = GetCurSel();
  158.      if(i == CB_ERR)
  159.         return 0;
  160.      return GetItemData(i);
  161.     }