189 lines
5.1 KiB
C++
189 lines
5.1 KiB
C++
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: Implements a combo box that autoselects items from the list as the
|
||
|
// user types in the edit control. It has the additional feature of
|
||
|
// being able to easily set the text color.
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "AutoSelCombo.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include "tier0/memdbgon.h"
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CAutoSelComboBox, CComboBox)
|
||
|
//{{AFX_MSG_MAP(CAutoSelComboBox)
|
||
|
ON_WM_CTLCOLOR()
|
||
|
ON_CONTROL_REFLECT_EX(CBN_EDITUPDATE, OnEditUpdate)
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Constructor.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CAutoSelComboBox::CAutoSelComboBox(void)
|
||
|
{
|
||
|
m_szLastText[0] = '\0';
|
||
|
m_dwTextColor = RGB(0, 0, 0);
|
||
|
m_bNotifyParent = true;
|
||
|
m_nLastSel = -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Attaches this object to the given dialog item.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CAutoSelComboBox::SubclassDlgItem(UINT nID, CWnd *pParent)
|
||
|
{
|
||
|
//
|
||
|
// Disable parent notifications for CControlBar-derived classes. This is
|
||
|
// necessary because these classes result in multiple message reflections
|
||
|
// unless we return TRUE from our message handler.
|
||
|
//
|
||
|
if (pParent->IsKindOf(RUNTIME_CLASS(CControlBar)))
|
||
|
{
|
||
|
m_bNotifyParent = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_bNotifyParent = true;
|
||
|
}
|
||
|
|
||
|
BaseClass::SubclassDlgItem(nID, pParent);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Automatically selects the first matching combo box item when the
|
||
|
// edit control's text changes.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CAutoSelComboBox::OnUpdateText(void)
|
||
|
{
|
||
|
int nCurSel = GetCurSel();
|
||
|
int nNewSel = nCurSel;
|
||
|
|
||
|
DWORD dwEditSel = GetEditSel();
|
||
|
int nEditStart = LOWORD(dwEditSel);
|
||
|
int nEditEnd = HIWORD(dwEditSel);
|
||
|
|
||
|
char szTypedText[MAX_PATH];
|
||
|
GetWindowText(szTypedText, sizeof(szTypedText));
|
||
|
|
||
|
//
|
||
|
// Select the first match in the list if what they typed is different from
|
||
|
// the current selection. This won't do anything if they are deleting characters
|
||
|
// from the end of the text.
|
||
|
//
|
||
|
int nTypedLen = strlen(szTypedText);
|
||
|
int nLastLen = strlen(m_szLastText);
|
||
|
|
||
|
bool bSearched = false;
|
||
|
int nIndex = CB_ERR;
|
||
|
if (strnicmp(szTypedText, m_szLastText, nTypedLen))
|
||
|
{
|
||
|
nIndex = FindString(-1, szTypedText);
|
||
|
bSearched = true;
|
||
|
}
|
||
|
else if (nTypedLen < nLastLen)
|
||
|
{
|
||
|
// They deleted characters, try to match the shorter string exactly.
|
||
|
nIndex = FindStringExact(-1, szTypedText);
|
||
|
bSearched = true;
|
||
|
}
|
||
|
|
||
|
if (bSearched)
|
||
|
{
|
||
|
if (nCurSel != nIndex)
|
||
|
{
|
||
|
SetCurSel(nIndex);
|
||
|
nNewSel = nIndex;
|
||
|
}
|
||
|
|
||
|
if (nIndex != CB_ERR)
|
||
|
{
|
||
|
// Found a match.
|
||
|
if ((nEditEnd == -1) || (nEditEnd == (int)strlen(szTypedText)))
|
||
|
{
|
||
|
SetEditSel(strlen(szTypedText), -1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetEditSel(nEditStart, nEditEnd);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// No match found.
|
||
|
SetWindowText(szTypedText);
|
||
|
SetEditSel(nEditStart, nEditEnd);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
strcpy(m_szLastText, szTypedText);
|
||
|
|
||
|
if (nNewSel != m_nLastSel)
|
||
|
{
|
||
|
GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), CBN_SELCHANGE), (LPARAM)m_hWnd);
|
||
|
m_nLastSel = nNewSel;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL CAutoSelComboBox::OnEditUpdate(void)
|
||
|
{
|
||
|
OnUpdateText();
|
||
|
|
||
|
//
|
||
|
// Despite MSDN's lies, returning FALSE here allows the parent
|
||
|
// window to hook the notification message as well, not TRUE.
|
||
|
//
|
||
|
return m_bNotifyParent ? FALSE : TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Resets the 'last typed text' buffer every time we gain/lose focus.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CAutoSelComboBox::OnSetFocus(CWnd *pOldWnd)
|
||
|
{
|
||
|
m_szLastText[0] = '\0';
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input : dwColor -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CAutoSelComboBox::SetTextColor(COLORREF dwColor)
|
||
|
{
|
||
|
m_dwTextColor = dwColor;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Called before painting to override default colors.
|
||
|
// Input : pDC - DEvice context being painted into.
|
||
|
// pWnd - Control asking for color.
|
||
|
// nCtlColor - Type of control asking for color.
|
||
|
// Output : Returns the handle of a brush to use as the background color.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HBRUSH CAutoSelComboBox::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)
|
||
|
{
|
||
|
HBRUSH hBrush = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
|
||
|
|
||
|
if (nCtlColor == CTLCOLOR_EDIT)
|
||
|
{
|
||
|
pDC->SetTextColor(m_dwTextColor);
|
||
|
}
|
||
|
|
||
|
return(hBrush);
|
||
|
}
|
||
|
|
||
|
|