📄 advcombobox.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// AdvComboBox.cpp : implementation file
//
// CAdvComboBox Control
// Version: 2.1
// Date: September 2002
// Author: Mathias Tunared
// Email: Mathias@inorbit.com
// Copyright (c) 2002. All Rights Reserved.
//
// This code, in compiled form or as source code, may be redistributed
// unmodified PROVIDING it is not sold for profit without the authors
// written consent, and providing that this notice and the authors name
// and all copyright notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AdvComboBox.h"
#include "GridCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define IDC_COMBOEDIT 108
/////////////////////////////////////////////////////////////////////////////
// CAdvComboBox
IMPLEMENT_DYNAMIC(CAdvComboBox, CWnd)
CAdvComboBox::CAdvComboBox( BOOL bInst )
:
m_pDropWnd(0),
m_bDropListVisible(0),
m_bInst( bInst )
{
RegisterWindowClass();
m_pEdit = NULL;
m_zDelta = 0;
m_nCurSel = -1;
m_bDropRectStored= false;
m_bHasFocus = false;
m_bHasSentFocus = false;
m_bSelItem = false;
m_bFirstPaint = true;
m_nMinVisItems = 5;
m_bCodeCreate = false;
m_bAutoAppend = TRUE;
m_bDropButtonHot = false;
m_bTrackMouseLeave = false;
m_nDefaultDropItems = -1;
m_dwACBStyle = 0;
m_dwACBStyle |= ACBS_STANDARD;
CFont fnt;
fnt.CreatePointFont(80,"Tahoma");
LOGFONT lf;
fnt.GetLogFont(&lf);
lf.lfHeight-=1;
m_pFont=new CFont;
m_pFont->CreateFontIndirect(&lf);
}
CAdvComboBox::~CAdvComboBox()
{
delete m_pFont;
if( m_pDropWnd )
{
m_pDropWnd->ShowWindow( SW_HIDE );
m_bDropListVisible = FALSE;
m_pDropWnd->DestroyWindow();
delete m_pDropWnd;
m_pDropWnd = NULL;
}
if( m_pEdit )
{
m_pEdit->DestroyWindow();
delete m_pEdit;
}
DestroyWindow();
}
BEGIN_MESSAGE_MAP(CAdvComboBox, CWnd)
//{{AFX_MSG_MAP(CAdvComboBox)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEWHEEL()
ON_WM_SIZE()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_SHOWWINDOW()
ON_WM_ENABLE()
ON_WM_CHILDACTIVATE()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_SELECTED_ITEM, OnSelectedItem )
ON_MESSAGE( WM_ON_DROPDOWN_BUTTON, OnDropdownButton )
ON_MESSAGE( WM_DESTROY_DROPLIST, OnDestroyDropdownList )
ON_EN_KILLFOCUS(IDC_COMBOEDIT, OnKillfocusEdit)
ON_EN_SETFOCUS(IDC_COMBOEDIT, OnSetfocusEdit)
ON_EN_CHANGE(IDC_COMBOEDIT, OnChangeEdit)
ON_EN_UPDATE(IDC_COMBOEDIT, OnUpdateEdit)
ON_MESSAGE( CB_ADDSTRING, OnAddString )
ON_MESSAGE( CB_SETCURSEL, OnSetCurSel )
ON_MESSAGE( CB_GETCURSEL, OnGetCurSel )
ON_MESSAGE( CB_SELECTSTRING, OnSelectString )
ON_MESSAGE( CB_GETCOUNT, OnGetCount )
ON_MESSAGE( CB_RESETCONTENT, OnResetContent )
ON_MESSAGE( CB_GETLBTEXT, OnGetLBText )
ON_MESSAGE( CB_GETLBTEXTLEN, OnGetLBTextLen )
ON_MESSAGE( CB_GETTOPINDEX, OnGetTopIndex )
ON_MESSAGE( CB_SETTOPINDEX, OnSetTopIndex )
END_MESSAGE_MAP()
void CAdvComboBox::SetFont(CFont* pFont){
LOGFONT lf;
pFont->GetLogFont(&lf);
m_pFont->DeleteObject();
m_pFont->CreateFontIndirect(&lf);
CWnd::SetFont(m_pFont);
}
/////////////////////////////////////////////////////////////////////////////
// CAdvComboBox message handlers
LONG CAdvComboBox::OnAddString( WPARAM wParam, LPARAM lString )
{
char* pStr = (char*)lString;
return AddString( pStr );
}
LONG CAdvComboBox::OnSetCurSel( WPARAM wIndex, LPARAM lParam )
{
int nIndex = (int)wIndex;
return SetCurSel( nIndex );
}
LONG CAdvComboBox::OnGetCurSel( WPARAM wParam, LPARAM lParam )
{
return GetCurSel();
}
LONG CAdvComboBox::OnSelectString( WPARAM wItemStart, LPARAM lString )
{
int nItem = (int)wItemStart;
char* pStr = (char*)lString;
int nIndex = FindStringExact( nItem, pStr );
return SetCurSel( nIndex );
}
LONG CAdvComboBox::OnGetCount( WPARAM wParam, LPARAM lParam )
{
return GetCount();
}
LONG CAdvComboBox::OnResetContent( WPARAM wParam, LPARAM lParam )
{
m_list.clear();
m_strEdit = "";
m_nCurSel = -1;
SetWindowText( "" );
if( m_pEdit )
{
m_pEdit->SetWindowText( "" );
}
Invalidate();
return CB_OKAY;
}
LONG CAdvComboBox::OnGetLBText( WPARAM wIndex, LPARAM lString )
{
int nIndex = (int)wIndex;
char* pOutStr = (char*)lString;
return GetLBText( nIndex, pOutStr );
}
LONG CAdvComboBox::OnGetLBTextLen( WPARAM wIndex, LPARAM lParam )
{
int nIndex = (int)wIndex;
return GetLBTextLen( nIndex );
}
LONG CAdvComboBox::OnGetTopIndex( WPARAM wParam, LPARAM lParam )
{
return GetTopIndex();
}
LONG CAdvComboBox::OnSetTopIndex( WPARAM wIndex, LPARAM lParam )
{
return SetTopIndex((int)wIndex);
}
BOOL CAdvComboBox::RegisterWindowClass()
{
WNDCLASS wndcls;
HINSTANCE hInst;
hInst = AfxGetInstanceHandle();
ASSERT( hInst != 0 );
if( !(::GetClassInfo(hInst, ADVCOMBOBOXCTRL_CLASSNAME, &wndcls)) )
{
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = ADVCOMBOBOXCTRL_CLASSNAME;
if( !AfxRegisterClass(&wndcls) )
{
AfxThrowResourceException();
return FALSE;
}
}
return TRUE;
}
BOOL CAdvComboBox::Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID )
{
m_rcCombo = rect;
m_bCodeCreate = true;
m_dwACBStyle |= ACBS_FLAT;
m_dwStyle = dwStyle;
LoadString( nID );
return CWnd::Create(NULL, "", dwStyle, m_rcCombo, pParentWnd, nID );
}
void CAdvComboBox::LoadString( UINT nStringID )
{
UINT nIDS;
if( nStringID )
nIDS = nStringID;
else
{
nIDS = GetWindowLong( GetSafeHwnd(), GWL_ID );
}
//
// Load string from resources
CString strItems;
if( !strItems.LoadString( nIDS ) )
{
return;
}
//
// Clear the list
m_list.clear();
//
// Go through the string and look after '\n'.
char seps[] = "\n";
char *token;
int nLen = strItems.GetLength();
char* szTok = new char[nLen+5];
memset( szTok, 0, nLen+5 );
strcpy( szTok, (LPCTSTR)strItems );
token = strtok( szTok, seps );
while( token != NULL )
{
AddString( token );
token = strtok( NULL, seps );
}
//
// Add item to list
}
int CAdvComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct){
if(CWnd::OnCreate(lpCreateStruct)==-1)return -1;
if((GetStyle()&CBS_DROPDOWN)&&!(GetStyle()&CBS_SIMPLE)){
CRect rect;
GetClientRect(rect);
rect.right = rect.right - ::GetSystemMetrics(SM_CXHSCROLL);
m_pEdit = new CGEdit;
DWORD dwStyle = 0;
dwStyle = WS_VISIBLE|WS_CHILD;
if(GetStyle()&CBS_AUTOHSCROLL)dwStyle|=ES_AUTOHSCROLL;
m_pEdit->Create(dwStyle,rect,this,IDC_COMBOEDIT);
m_pEdit->SetFont(m_pFont);
m_pEdit->SetWindowText(m_strEdit.c_str());
}
return 0;
}
void CAdvComboBox::PreSubclassWindow(){
}
void CAdvComboBox::OnChildActivate(){
CWnd::OnChildActivate();
}
void CAdvComboBox::OnPaint()
{
CPaintDC dc(this); // device context for painting
if( m_nCurSel != -1 )
{
m_iter = m_list.begin();
advance( m_iter, m_nCurSel );
if( m_iter != m_list.end() )
{
m_strEdit = m_iter->strText;
}
if( m_bFirstPaint )
{
if( m_pEdit )
{
m_pEdit->SetWindowText( m_strEdit.c_str() );
m_bFirstPaint = false;
m_pEdit->EnableWindow( IsWindowEnabled() );
}
}
}
// TODO: Add your message handler code here
CRect rect;
CRect rcText;
GetClientRect(rect);
rcText = rect;
rect.left = rect.right - ::GetSystemMetrics(SM_CXHSCROLL);
rcText.right = rect.left-1;
m_rcDropButton = rect;
GetClientRect(rect);
BOOL bWndEnabled = IsWindowEnabled();
COLORREF clrDisabledBkg = G_EDIT_RDNL_CLR;//::GetSysColor(COLOR_BTNFACE);
COLORREF clrDisabledBorder = ::GetSysColor(COLOR_3DDKSHADOW);
COLORREF clrDisabledText = ::GetSysColor(COLOR_GRAYTEXT);
if( !bWndEnabled )
{
if( 1 ) // Draw disabled flat control with border? Change to '0'.
{
dc.FillSolidRect( rect, clrDisabledBkg );
}
else
{
CBrush brDisabled(clrDisabledBkg);
CBrush* pOldBrush = dc.SelectObject(&brDisabled);
CPen penDisabled( PS_SOLID, 0, clrDisabledBorder);
CPen* pOldPen = dc.SelectObject(&penDisabled);
dc.Rectangle(rect);
dc.SelectObject(pOldBrush);
dc.SelectObject(pOldPen);
}
}
else
{
COLORREF clrEnabledBkg = ::GetSysColor(COLOR_WINDOW);
dc.FillSolidRect( rect, clrEnabledBkg );
}
DWORD dwBtnStyle = 0;
if(!bWndEnabled )dwBtnStyle|=DFCS_INACTIVE;
dwBtnStyle|=m_bDropListVisible?(DFCS_SCROLLDOWN|DFCS_PUSHED|DFCS_FLAT):(DFCS_SCROLLDOWN|DFCS_FLAT);
if( m_dwACBStyle & ACBS_FLAT )dc.DrawFrameControl(m_rcDropButton, DFC_SCROLL, dwBtnStyle );
else if( m_dwACBStyle & ACBS_STANDARD ){
COLORREF clrTopLeft = ::GetSysColor(COLOR_3DSHADOW);
COLORREF clrBottomRight = ::GetSysColor(COLOR_3DHILIGHT);
dc.Draw3dRect( &rect, clrTopLeft, clrBottomRight );
clrTopLeft = ::GetSysColor(COLOR_3DDKSHADOW);
clrBottomRight = ::GetSysColor(COLOR_3DLIGHT);
rect.DeflateRect(1,1);
dc.Draw3dRect( &rect, clrTopLeft, clrBottomRight );
m_rcDropButton.DeflateRect(0,2,0,2);
m_rcDropButton.left -= 2;
m_rcDropButton.right -= 2;
dc.DrawFrameControl(m_rcDropButton, DFC_SCROLL, dwBtnStyle );
rcText.DeflateRect(4,3,2,3);
}
if((GetStyle()&CBS_DROPDOWN)&&(GetStyle()&CBS_SIMPLE)){
//
// Draw Text as selected
COLORREF clrBackground;
COLORREF clrOldBkColor;
COLORREF clrOldTextColor;
clrBackground = ::GetSysColor(COLOR_HIGHLIGHT);
clrOldBkColor = dc.SetBkColor( clrBackground );
// clrOldTextColor = dc.SetTextColor( ::GetSysColor(COLOR_HIGHLIGHTTEXT) );
int nOldBkMode = dc.SetBkMode( TRANSPARENT );
CFont* pOldFont = dc.SelectObject( m_pFont );
if( m_bHasFocus && !m_bDropListVisible )
{
dc.FillSolidRect( rcText, bWndEnabled ? clrBackground : clrDisabledBkg );
clrOldTextColor = dc.SetTextColor( bWndEnabled ? ::GetSysColor(COLOR_HIGHLIGHTTEXT) : clrDisabledText );
rcText.left+=3;
dc.DrawText( m_strEdit.c_str(), &rcText, DT_SINGLELINE|DT_VCENTER);
}
else
{
dc.FillSolidRect( rcText, bWndEnabled ? ::GetSysColor(COLOR_HIGHLIGHTTEXT) : clrDisabledBkg );
clrOldTextColor = dc.SetTextColor( bWndEnabled ? ::GetSysColor(COLOR_BTNTEXT) : clrDisabledText );
rcText.left+=3;
dc.DrawText( m_strEdit.c_str(), &rcText, DT_SINGLELINE|DT_VCENTER);
}
dc.SelectObject( pOldFont );
dc.SetBkMode( nOldBkMode );
}
else
{
//if( m_pEdit )
//{
// m_pEdit->SetFont( m_pFont );
//}
}
// Do not call CWnd::OnPaint() for painting messages
}
BOOL CAdvComboBox::OnEraseBkgnd(CDC* pDC)
{
return CWnd::OnEraseBkgnd(pDC);
// return TRUE;
}
int CAdvComboBox::SetItemHeight(int nIndex, int nHeight)
{
if( nIndex == -1 )
{
if( nHeight < 10 || nHeight > 50 )
{
return CB_ERR;
}
else
{
//
// Button rect
GetClientRect(m_rcDropButton);
m_rcDropButton.left = m_rcDropButton.right - ::GetSystemMetrics(SM_CXHSCROLL);
return 0;
}
}
return CB_ERR;
}
void CAdvComboBox::OnLButtonDown(UINT nFlags, CPoint point)
{
if( GetFocus() != this )
{
SetFocus();
}
//
// Is mouse over drop button?
if( (GetStyle() & CBS_DROPDOWN) && !(GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWN
{
if( m_rcDropButton.PtInRect( point ) )
{
SendMessage( WM_ON_DROPDOWN_BUTTON );
InvalidateRect( m_rcDropButton );
Invalidate();
}
}
else
if( (GetStyle() & CBS_DROPDOWN) && (GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWNLIST
{
CRect rc = m_rcCombo;
GetClientRect( &rc );
if( rc.PtInRect( point ) )
{
SendMessage( WM_ON_DROPDOWN_BUTTON );
Invalidate();
}
}
CWnd::OnLButtonDown(nFlags, point);
}
LONG CAdvComboBox::OnSelectedItem( WPARAM wParam, LPARAM lParam )
{
list<LIST_ITEM> itemlist;
list<LIST_ITEM>::iterator itemiter;
int nPos = (int)wParam;
itemlist = m_pDropWnd->GetList();
itemiter = itemlist.begin();
advance( itemiter, nPos );
m_strEdit = itemiter->strText;
m_nCurSel = FindStringExact( 0, m_strEdit.c_str() );
SetWindowText( m_strEdit.c_str() );
if( (GetStyle() & CBS_DROPDOWN) && !(GetStyle() & CBS_SIMPLE) ) // == CBS_DROPDOWN
{
if( m_pEdit )
{
m_pEdit->SetWindowText( m_strEdit.c_str() );
m_pEdit->SetFocus();
m_pEdit->SetSel( 0, -1, TRUE );
}
}
// Send message to parent(dialog)
m_bSelItem = true;
int nId = GetDlgCtrlID();
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_SELENDOK), (LPARAM)m_hWnd );
Invalidate();
OnDestroyDropdownList(0,0);
//
// See to it that the drop button is redrawn
InvalidateRect( m_rcDropButton );
GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(nId,CBN_SELCHANGE), (LPARAM)m_hWnd );
return TRUE;
}
LONG CAdvComboBox::OnDropdownButton( WPARAM wParam, LPARAM lParam )
{
//
//
if( !m_bDropListVisible )
{
//
// Button is pressed
//
// Create list
if( !m_pDropWnd )
{
CreateDropList( m_list );
}
m_pDropWnd->ShowWindow( SW_SHOW );
m_bDropListVisible = TRUE;
}
else
{
OnDestroyDropdownList(0,0);
}
// Return TRUE if OK to go back, else return FALSE.
return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -