📄 advcombobox.cpp
字号:
if( pMsg->wParam == VK_RETURN )
{
// OutputDebugString( "(RETURN)\n" );
if( m_pDropWnd )
{
int nPos = m_pDropWnd->GetListBoxPtr()->GetCurSel();
SendMessage( WM_SELECTED_ITEM, (WPARAM)nPos );
}
else
{
return CWnd::PreTranslateMessage(pMsg);
}
}
else
if( pMsg->wParam == VK_ESCAPE )
{
// OutputDebugString( "(ESCAPE)\n" );
if( m_pDropWnd )
{
OnDestroyDropdownList(0,0);
Invalidate();
}else return CWnd::PreTranslateMessage(pMsg);
}
else
if( pMsg->wParam == VK_F4 )
{
// OutputDebugString( "(F4)\n" );
SendMessage( WM_ON_DROPDOWN_BUTTON );
Invalidate();
}
else
if( pMsg->wParam == VK_UP )
{
// OutputDebugString( "(VK_UP)\n" );
SelPrevItem();
}
else
if( pMsg->wParam == VK_DOWN )
{
// OutputDebugString( "(VK_DOWN)\n" );
SelNextItem();
}
else
if( pMsg->wParam == VK_DELETE || pMsg->wParam == VK_BACK )
{
m_bAutoAppend = FALSE;
return CWnd::PreTranslateMessage(pMsg);
}
else
if( pMsg->wParam == VK_RIGHT )
{
if( m_dwACBStyle & ACBS_AUTOAPPEND )
{
// If the cursor is at the end of the text, show autosuggest text
if( m_pEdit )
{
int nS, nE;
m_pEdit->GetSel( nS, nE );
if( nS == nE && nS == m_pEdit->LineLength() )
{
OnUpdateEdit();
}
else
{
return CWnd::PreTranslateMessage(pMsg);
}
}
}
else
{
return CWnd::PreTranslateMessage(pMsg);
}
}
else
{
// OutputDebugString( "<not handled>\n" );
return CWnd::PreTranslateMessage(pMsg);
}
return TRUE;
}
else
if( pMsg->message == WM_SYSKEYDOWN )
{
if( pMsg->wParam == VK_DOWN ||
pMsg->wParam == VK_UP )
{
// OutputDebugString( "(ALT-VK_DOWN)\n" );
SendMessage( WM_ON_DROPDOWN_BUTTON );
Invalidate();
}
}
return CWnd::PreTranslateMessage(pMsg);
}
void CAdvComboBox::SelPrevItem()
{
if( m_pDropWnd )
{
int nPos = m_pDropWnd->GetListBoxPtr()->GetCurSel();
if( nPos > 0 )
{
m_pDropWnd->GetListBoxPtr()->SetCurSel( --nPos );
}
}
else
{
m_iter = m_list.begin();
advance( m_iter, m_nCurSel );
--m_iter;
int nOldSel = m_nCurSel;
int nPos = m_nCurSel;
while( m_iter != m_list.end() )
{
nPos--;
if( !m_iter->bDisabled )
{
m_strEdit = m_iter->strText;
if( m_pEdit )
m_pEdit->SetWindowText( m_strEdit.c_str() );
m_nCurSel = nPos;
Invalidate();
break;
}
--m_iter;
}
if( nOldSel != m_nCurSel )
{
// Send message to parent(dialog)
int nId = GetDlgCtrlID();
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_SELENDOK), (LPARAM)m_hWnd );
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_SELCHANGE), (LPARAM)m_hWnd );
}
}
}
void CAdvComboBox::SelNextItem()
{
if( m_pDropWnd )
{
int nPos = m_pDropWnd->GetListBoxPtr()->GetCurSel();
if( nPos < m_pDropWnd->GetListBoxPtr()->GetCount() )
{
m_pDropWnd->GetListBoxPtr()->SetCurSel( ++nPos );
}
}
else
{
m_iter = m_list.begin();
advance( m_iter, m_nCurSel );
++m_iter;
int nOldSel = m_nCurSel;
int nPos = m_nCurSel;
while( m_iter != m_list.end() )
{
nPos++;
if( !m_iter->bDisabled )
{
m_strEdit = m_iter->strText;
if( m_pEdit )
m_pEdit->SetWindowText( m_strEdit.c_str() );
Invalidate();
m_nCurSel = nPos;
break;
}
++m_iter;
}
if( nOldSel != m_nCurSel )
{
// Send message to parent(dialog)
int nId = GetDlgCtrlID();
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_SELENDOK), (LPARAM)m_hWnd );
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_SELCHANGE), (LPARAM)m_hWnd );
}
}
}
int CAdvComboBox::GetTopIndex()
{
if( m_bDropListVisible )
{
if( m_pDropWnd )
{
return m_pDropWnd->GetListBoxPtr()->GetTopIndex();
}
}
return CB_ERR;
}
int CAdvComboBox::SetTopIndex(int nIndex)
{
if( m_bDropListVisible )
{
if( m_pDropWnd )
{
return m_pDropWnd->GetListBoxPtr()->SetTopIndex(nIndex);
}
}
return CB_ERR;
}
//
// Will not allocate anything. I can't see the need in doing that.
// Everything is stored in a STL list.
int CAdvComboBox::InitStorage(int nItems, UINT nBytes)
{
return nItems;
}
void CAdvComboBox::ShowDropDown(BOOL bShowIt)
{
if( bShowIt )
{
if( !m_bDropListVisible )
{
SendMessage( WM_ON_DROPDOWN_BUTTON );
Invalidate();
}
}
else
{
if( m_bDropListVisible )
{
SendMessage( WM_DESTROY_DROPLIST );
Invalidate();
}
}
}
void CAdvComboBox::GetDroppedControlRect(LPRECT lprect)
{
if( m_bDropListVisible )
{
m_pDropWnd->GetWindowRect( lprect );
}
}
BOOL CAdvComboBox::GetDroppedState()
{
return m_bDropListVisible;
}
int CAdvComboBox::SetExtendedUI(BOOL bExtended)
{
return CB_OKAY;
}
BOOL CAdvComboBox::GetExtendedUI()
{
return FALSE;
}
int CAdvComboBox::DeleteString(UINT nIndex)
{
m_iter = m_list.begin();
advance( m_iter, nIndex );
if( m_iter != m_list.end() || nIndex > m_list.size() )
{
m_list.erase( m_iter );
return (int)m_list.size();
}
else
{
return CB_ERR;
}
}
int CAdvComboBox::InsertString(int nIndex, LPCTSTR lpszString)
{
LIST_ITEM item;
item.strText = lpszString;
if( nIndex == -1 || (nIndex > (int)m_list.size()) )
{
m_list.push_back( item );
return (int)m_list.size()-1;
}
if( nIndex == 0 && (m_list.size()==0) )
{
m_list.push_back( item );
return 0;
}
m_iter = m_list.begin();
advance( m_iter, nIndex );
if( m_iter != m_list.end() )
{
m_iter = m_list.insert( m_iter, item );
int nPos = 0;
while( m_iter != m_list.begin() )
{
nPos++;
--m_iter;
}
if( nIndex <= m_nCurSel )
{
m_nCurSel++;
}
return nPos;
}
return CB_ERR;
}
DWORD CAdvComboBox::GetEditSel()
{
if( (GetStyle() & CBS_DROPDOWN) && !(GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWN
{
if( m_pEdit )
{
return m_pEdit->GetSel();
}
}
return CB_ERR;
}
BOOL CAdvComboBox::SetEditSel(int nStartChar, int nEndChar)
{
if( (GetStyle() & CBS_DROPDOWN) && !(GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWN
{
if( m_pEdit )
{
m_pEdit->SetSel( nStartChar, nEndChar, TRUE );
return TRUE;
}
}
return CB_ERR;
}
void CAdvComboBox::OnChangeEdit()
{
if( !m_pDropWnd )
{
// Send message to parent(dialog)
int nId = GetDlgCtrlID();
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_EDITCHANGE), (LPARAM)m_hWnd );
}
}
void CAdvComboBox::OnUpdateEdit()
{
static bool bAutoAppendInProgress;
CString strEdit;
m_pEdit->GetWindowText( strEdit );
if( GetFocus() == m_pEdit )
{
if( !bAutoAppendInProgress )
{
// m_nCurSel = -1;
if( m_dwACBStyle & ACBS_AUTOAPPEND && m_bAutoAppend )
{
string str = (LPCTSTR)strEdit;
int nEditLen = (int)str.length();
if( !nEditLen )
return;
int nStartSel;
int nEndSel;
m_pEdit->GetSel( nStartSel, nEndSel );
LIST_ITEM item;
m_iter = m_list.begin();
while( m_iter != m_list.end() )
{
item = *m_iter;
int nPos = (int)m_iter->strText.find( str, 0 );
if( nPos == 0 )
{
bAutoAppendInProgress = true;
m_pEdit->SetWindowText( m_iter->strText.c_str() );
m_pEdit->SetSel( nEditLen, (int)m_iter->strText.length(), TRUE );
bAutoAppendInProgress = false;
break;
}
++m_iter;
}
}
}
if( !bAutoAppendInProgress )
{
if( m_dwACBStyle & ACBS_AUTOSUGGEST )
{
list<LIST_ITEM> suggestlist;
list<LIST_ITEM>::iterator suggestiter;
string str = (LPCTSTR)strEdit;
int nEditLen = (int)str.length();
if( !nEditLen )
{
if( m_pDropWnd )
SendMessage( WM_DESTROY_DROPLIST );
return;
}
int nStartSel;
int nEndSel;
m_pEdit->GetSel( nStartSel, nEndSel );
LIST_ITEM item;
m_iter = m_list.begin();
while( m_iter != m_list.end() )
{
item = *m_iter;
int nPos = (int)m_iter->strText.find( str, 0 );
if( nPos == 0 )
{
suggestlist.push_back( item );
}
++m_iter;
}
if( m_pDropWnd )
SendMessage( WM_DESTROY_DROPLIST );
if( suggestlist.size() != 0 )
CreateDropList( suggestlist );
}
}
}
if( !m_pDropWnd )
{
// Send message to parent(dialog)
int nId = GetDlgCtrlID();
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_EDITUPDATE), (LPARAM)m_hWnd );
}
}
void CAdvComboBox::OnEnable(BOOL bEnable)
{
CWnd::OnEnable(bEnable);
Invalidate();
if( m_pEdit )
{
m_pEdit->EnableWindow( bEnable );
}
}
BOOL CAdvComboBox::LimitText(int nMaxChars)
{
if( m_pEdit )
{
int nCh = !nMaxChars ? 65535 : nMaxChars;
m_pEdit->SetLimitText( nCh );
return TRUE;
}
else
{
return CB_ERR;
}
}
void CAdvComboBox::SetMinVisibleItems(int nMinItems)
{
m_nMinVisItems = nMinItems;
}
int CAdvComboBox::GetMinVisibleItems()
{
return m_nMinVisItems;
}
void CAdvComboBox::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
bool bChange = m_bDropButtonHot;
if( (GetStyle() & CBS_DROPDOWN) && !(GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWN
{
if( m_rcDropButton.PtInRect( point ) )
{
m_bDropButtonHot = true;
}
else
{
m_bDropButtonHot = false;
}
}
else
if( (GetStyle() & CBS_DROPDOWN) && (GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWNLIST
{
GetClientRect( &m_rcCombo );
if( m_rcCombo.PtInRect( point ) )
{
m_bDropButtonHot = true;
}
else
{
m_bDropButtonHot = false;
}
}
if( bChange != m_bDropButtonHot )
{
if( !m_bTrackMouseLeave )
{
//
// Could not use TrackMouseEvent() under Release. A bug appeared
// the second time the dropwindow was shown, and I did not
// have to strenght to go look for it. :)
/* TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
TrackMouseEvent(&tme);*/
m_bTrackMouseLeave = true;
SetTimer(1, 50, NULL);
}
InvalidateRect( &m_rcDropButton );
}
CWnd::OnMouseMove(nFlags, point);
/*RECT rct;
GetWindowRect(&rct);
CWnd* pWnd(GetParent());
pWnd->ScreenToClient(&rct);
point.Offset(rct.left,rct.top);
pWnd->PostMessage(WM_MOUSEMOVE,(WPARAM)nFlags,LPARAM(point.y<<16|point.x));*/
}
void CAdvComboBox::OnMouseLeave()
{
// TODO: Add your message handler code here and/or call default
bool bChange = m_bDropButtonHot;
m_bDropButtonHot = false;
m_bTrackMouseLeave = false;
if( bChange != m_bDropButtonHot )
InvalidateRect( &m_rcDropButton );
}
void CAdvComboBox::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if( nIDEvent == 1 )
{
CPoint point;
GetCursorPos( &point );
ScreenToClient( &point );
if( (GetStyle() & CBS_DROPDOWN) && !(GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWN
{
if( !m_rcDropButton.PtInRect( point ) )
{
KillTimer( 1 );
OnMouseLeave();
}
}
else
if( (GetStyle() & CBS_DROPDOWN) && (GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWNLIST
{
GetClientRect( &m_rcCombo );
if( !m_rcCombo.PtInRect( point ) )
{
KillTimer( 1 );
OnMouseLeave();
}
}
}
CWnd::OnTimer(nIDEvent);
}
int CAdvComboBox::GetDefaultVisibleItems()
{
return m_nDefaultDropItems;
}
void CAdvComboBox::SetDefaultVisibleItems(int nItems)
{
m_nDefaultDropItems = nItems;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -