⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 advcombobox.cpp

📁 EVC的Grid ctrl应用,有需要的朋友可以联系我哦
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////
// 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 + -