Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
5.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implements a combo box that autoselects items from the list as the
  4. // user types in the edit control. It has the additional feature of
  5. // being able to easily set the text color.
  6. //
  7. //=============================================================================//
  8. #include "stdafx.h"
  9. #include "AutoSelCombo.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. BEGIN_MESSAGE_MAP(CAutoSelComboBox, CComboBox)
  13. //{{AFX_MSG_MAP(CAutoSelComboBox)
  14. ON_WM_CTLCOLOR()
  15. ON_CONTROL_REFLECT_EX(CBN_EDITUPDATE, OnEditUpdate)
  16. //}}AFX_MSG_MAP
  17. END_MESSAGE_MAP()
  18. //-----------------------------------------------------------------------------
  19. // Purpose: Constructor.
  20. //-----------------------------------------------------------------------------
  21. CAutoSelComboBox::CAutoSelComboBox(void)
  22. {
  23. m_szLastText[0] = '\0';
  24. m_dwTextColor = RGB(0, 0, 0);
  25. m_bNotifyParent = true;
  26. m_nLastSel = -1;
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Purpose: Attaches this object to the given dialog item.
  30. //-----------------------------------------------------------------------------
  31. void CAutoSelComboBox::SubclassDlgItem(UINT nID, CWnd *pParent)
  32. {
  33. //
  34. // Disable parent notifications for CControlBar-derived classes. This is
  35. // necessary because these classes result in multiple message reflections
  36. // unless we return TRUE from our message handler.
  37. //
  38. if (pParent->IsKindOf(RUNTIME_CLASS(CControlBar)))
  39. {
  40. m_bNotifyParent = false;
  41. }
  42. else
  43. {
  44. m_bNotifyParent = true;
  45. }
  46. BaseClass::SubclassDlgItem(nID, pParent);
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose: Automatically selects the first matching combo box item when the
  50. // edit control's text changes.
  51. //-----------------------------------------------------------------------------
  52. void CAutoSelComboBox::OnUpdateText(void)
  53. {
  54. int nCurSel = GetCurSel();
  55. int nNewSel = nCurSel;
  56. DWORD dwEditSel = GetEditSel();
  57. int nEditStart = LOWORD(dwEditSel);
  58. int nEditEnd = HIWORD(dwEditSel);
  59. char szTypedText[MAX_PATH];
  60. GetWindowText(szTypedText, sizeof(szTypedText));
  61. //
  62. // Select the first match in the list if what they typed is different from
  63. // the current selection. This won't do anything if they are deleting characters
  64. // from the end of the text.
  65. //
  66. int nTypedLen = strlen(szTypedText);
  67. int nLastLen = strlen(m_szLastText);
  68. bool bSearched = false;
  69. int nIndex = CB_ERR;
  70. if (strnicmp(szTypedText, m_szLastText, nTypedLen))
  71. {
  72. nIndex = FindString(-1, szTypedText);
  73. bSearched = true;
  74. }
  75. else if (nTypedLen < nLastLen)
  76. {
  77. // They deleted characters, try to match the shorter string exactly.
  78. nIndex = FindStringExact(-1, szTypedText);
  79. bSearched = true;
  80. }
  81. if (bSearched)
  82. {
  83. if (nCurSel != nIndex)
  84. {
  85. SetCurSel(nIndex);
  86. nNewSel = nIndex;
  87. }
  88. if (nIndex != CB_ERR)
  89. {
  90. // Found a match.
  91. if ((nEditEnd == -1) || (nEditEnd == (int)strlen(szTypedText)))
  92. {
  93. SetEditSel(strlen(szTypedText), -1);
  94. }
  95. else
  96. {
  97. SetEditSel(nEditStart, nEditEnd);
  98. }
  99. }
  100. else
  101. {
  102. // No match found.
  103. SetWindowText(szTypedText);
  104. SetEditSel(nEditStart, nEditEnd);
  105. }
  106. }
  107. strcpy(m_szLastText, szTypedText);
  108. if (nNewSel != m_nLastSel)
  109. {
  110. GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), CBN_SELCHANGE), (LPARAM)m_hWnd);
  111. m_nLastSel = nNewSel;
  112. }
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose:
  116. //-----------------------------------------------------------------------------
  117. BOOL CAutoSelComboBox::OnEditUpdate(void)
  118. {
  119. OnUpdateText();
  120. //
  121. // Despite MSDN's lies, returning FALSE here allows the parent
  122. // window to hook the notification message as well, not TRUE.
  123. //
  124. return m_bNotifyParent ? FALSE : TRUE;
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Purpose: Resets the 'last typed text' buffer every time we gain/lose focus.
  128. //-----------------------------------------------------------------------------
  129. void CAutoSelComboBox::OnSetFocus(CWnd *pOldWnd)
  130. {
  131. m_szLastText[0] = '\0';
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Purpose:
  135. // Input : dwColor -
  136. //-----------------------------------------------------------------------------
  137. void CAutoSelComboBox::SetTextColor(COLORREF dwColor)
  138. {
  139. m_dwTextColor = dwColor;
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Purpose: Called before painting to override default colors.
  143. // Input : pDC - DEvice context being painted into.
  144. // pWnd - Control asking for color.
  145. // nCtlColor - Type of control asking for color.
  146. // Output : Returns the handle of a brush to use as the background color.
  147. //-----------------------------------------------------------------------------
  148. HBRUSH CAutoSelComboBox::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)
  149. {
  150. HBRUSH hBrush = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
  151. if (nCtlColor == CTLCOLOR_EDIT)
  152. {
  153. pDC->SetTextColor(m_dwTextColor);
  154. }
  155. return(hBrush);
  156. }