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

📄 listboxst.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "ListBoxST.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define	MASK_DWDATA		0x01	// dwItemData is valid
#define	MASK_LPDATA		0x02	// pData is valid
#define	MASK_NIMAGE		0x04	// nImage is valid
#define	MASK_DWFLAGS	0x08	// dwFlags is valid
#define MASK_ALL		0xff	// All fields are valid
#define TEST_BIT0		0x00000001
#define	LBST_CX_BORDER	3
#define	LBST_CY_BORDER	2

CListBoxST::CListBoxST()
{
	// No image list associated
	m_pImageList = NULL;
	::ZeroMemory(&m_szImage, sizeof(m_szImage));

	// By default, hilight full list box item
	SetRowSelect(ST_FULLROWSELECT, FALSE);
}

CListBoxST::~CListBoxST()
{
}

BEGIN_MESSAGE_MAP(CListBoxST, CListBox)
	//{{AFX_MSG_MAP(CListBoxST)
	ON_WM_DESTROY()
	ON_CONTROL_REFLECT_EX(LBN_DBLCLK, OnReflectedDblclk)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CListBoxST::OnDestroy() 
{
	FreeResources();
	CListBox::OnDestroy();
} // End of OnDestroy

void CListBoxST::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	ASSERT(lpMeasureItemStruct->CtlType == ODT_LISTBOX);
	CDC*    pDC = GetDC();
	int		nHeight = 0;
	
	CString	sText;
	CListBox::GetText(lpMeasureItemStruct->itemID, sText);

	CRect	csRect(0, 0, lpMeasureItemStruct->itemWidth, lpMeasureItemStruct->itemHeight);
	nHeight = pDC->DrawText(sText, -1, csRect, DT_WORDBREAK | DT_EXPANDTABS | DT_CALCRECT);

	if (m_pImageList)
		lpMeasureItemStruct->itemHeight = max(nHeight, m_szImage.cy + LBST_CY_BORDER*2);
	else
		lpMeasureItemStruct->itemHeight  = nHeight;

	lpMeasureItemStruct->itemHeight += LBST_CY_BORDER*2;

	ReleaseDC(pDC);
} // End of MeasureItem

void CListBoxST::DrawItem(LPDRAWITEMSTRUCT pDIStruct)
{
	CDC*			pDC = CDC::FromHandle(pDIStruct->hDC);
	BOOL			bIsSelected = FALSE;
	BOOL			bIsFocused = FALSE;
	BOOL			bIsDisabled = FALSE;
	COLORREF		crNormal = GetSysColor(COLOR_WINDOW);
	COLORREF		crSelected = GetSysColor(COLOR_HIGHLIGHT);
	COLORREF		crText = GetSysColor(COLOR_WINDOWTEXT);
	COLORREF		crColor = RGB(0, 0, 0);
	CString			sText;					// List box item text
	STRUCT_LBDATA*	lpLBData = NULL;

	lpLBData = (STRUCT_LBDATA*)CListBox::GetItemDataPtr(pDIStruct->itemID);
	if (lpLBData == NULL || lpLBData == (LPVOID)-1L)	return;

	bIsSelected = (pDIStruct->itemState & ODS_SELECTED);
	bIsFocused = (pDIStruct->itemState & ODS_FOCUS);
	bIsDisabled = ((pDIStruct->itemState & ODS_DISABLED) || ((lpLBData->dwFlags & TEST_BIT0) == TEST_BIT0));

	CRect rcItem = pDIStruct->rcItem;
	CRect rcIcon = pDIStruct->rcItem;
	CRect rcText = pDIStruct->rcItem;
	CRect rcCenteredText = pDIStruct->rcItem;

	pDC->SetBkMode(TRANSPARENT);

	// ONLY FOR DEBUG 
	//CBrush brBtnShadow(RGB(255, 0, 0));
	//pDC->FrameRect(&rcItem, &brBtnShadow);

	// Calculate rcIcon
	if (m_pImageList)
	{
		rcIcon.right = rcIcon.left + m_szImage.cx + LBST_CX_BORDER*2;
		rcIcon.bottom = rcIcon.top + m_szImage.cy + LBST_CY_BORDER*2;
	} // if
	else rcIcon.SetRect(0, 0, 0, 0);

	// Calculate rcText
	rcText.left = rcIcon.right;

	// Calculate rcCenteredText
	// Get list box item text
	CListBox::GetText(pDIStruct->itemID, sText);
	rcCenteredText = rcText;
	pDC->DrawText(sText, -1, rcCenteredText, DT_WORDBREAK | DT_EXPANDTABS| DT_CALCRECT | lpLBData->nFormat);
	rcCenteredText.OffsetRect(0, (rcText.Height() - rcCenteredText.Height())/2);

	// Draw rcIcon background
	if (m_pImageList)
	{
		if (bIsSelected && (m_byRowSelect == ST_FULLROWSELECT) && !bIsDisabled)
			crColor = crSelected;
		else
			crColor = crNormal;

		OnDrawIconBackground(pDIStruct->itemID, pDC, &rcItem, &rcIcon, bIsDisabled, bIsSelected, crColor);
	} // if

	// Draw rcText/rcCenteredText background
	if (bIsDisabled)
	{
		pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
		crColor = crNormal;
	} // if
	else
	{
		if (bIsSelected)
		{
			pDC->SetTextColor(0x00FFFFFF & ~crText);
			crColor = crSelected;
		} // if
		else
		{
			pDC->SetTextColor(crText);
			crColor = crNormal;
		} // else
	} // else

	if (m_byRowSelect == ST_TEXTSELECT)
		//pDC->FillSolidRect(&rcCenteredText, crColor);
		OnDrawTextBackground(pDIStruct->itemID, pDC, &rcItem, &rcCenteredText, bIsDisabled, bIsSelected, crColor);
	else
		//pDC->FillSolidRect(&rcText, crColor);
		OnDrawTextBackground(pDIStruct->itemID, pDC, &rcItem, &rcText, bIsDisabled, bIsSelected, crColor);

	// Draw the icon (if any)
	if (m_pImageList)
		OnDrawIcon(pDIStruct->itemID, pDC, &rcItem, &rcIcon, lpLBData->nImage, bIsDisabled, bIsSelected);

	// Draw text
	pDC->DrawText(sText, -1, rcCenteredText, DT_WORDBREAK | DT_EXPANDTABS | lpLBData->nFormat);

	// Draw focus rectangle
	if (bIsFocused && !bIsDisabled)
	{
		switch (m_byRowSelect)
		{
			case ST_FULLROWSELECT:
				pDC->DrawFocusRect(&rcItem);
				break;
			case ST_FULLTEXTSELECT:
				pDC->DrawFocusRect(&rcText);
				break;
			case ST_TEXTSELECT:
			default:
				pDC->DrawFocusRect(&rcCenteredText);
				break;
		} // switch
	} // if
} // End of DrawItem

// This function is called every time the background of the area that will contain
// the icon of a list box item needs to be drawn.
// This is a virtual function that can be rewritten in CListBoxST-derived classes
// to produce a whole range of effects not available by default.
// If the list box has no image list associated this function will not be called.
//
// Parameters:
//		[IN]	nIndex
//				Specifies the zero-based index of the item.
//		[IN]	pDC
//				Pointer to a CDC object that indicates the device context.
//		[IN]	prcItem
//				Pointer to a CRect object that indicates the bounds of the whole
//				list box item (icon + text).
//		[IN]	prcIcon
//				Pointer to a CRect object that indicates the bounds of the
//				area where the icon should be drawn.
//		[IN]	bIsDisabled
//				TRUE if the list box or the item is disabled, otherwise FALSE.
//		[IN]	bIsSelected
//				TRUE if the list box item is selected, otherwise FALSE.
//		[IN]	crSuggestedColor
//				A COLORREF value containing a suggested color for the background.
//
// Return value:
//		0 (Zero)
//			Function executed successfully.
//
DWORD CListBoxST::OnDrawIconBackground(int nIndex, CDC* pDC, CRect* prcItem, CRect* prcIcon, BOOL bIsDisabled, BOOL bIsSelected, COLORREF crSuggestedColor)
{
	pDC->SetBkColor(crSuggestedColor);
	pDC->FillSolidRect(prcIcon->left, prcIcon->top, prcIcon->Width(), prcItem->Height(), crSuggestedColor);

	return 0;
} // End of OnDrawIconBackground

// This function is called every time the background of the area that will contain
// the text of a list box item needs to be drawn.
// This is a virtual function that can be rewritten in CListBoxST-derived classes
// to produce a whole range of effects not available by default.
//
// Parameters:
//		[IN]	nIndex
//				Specifies the zero-based index of the item.
//		[IN]	pDC
//				Pointer to a CDC object that indicates the device context.
//		[IN]	prcItem
//				Pointer to a CRect object that indicates the bounds of the whole
//				list box item (icon + text).
//		[IN]	prcText
//				Pointer to a CRect object that indicates the bounds of the
//				area where the text should be drawn. This area reflects the current
//				row selection type.
//		[IN]	bIsDisabled
//				TRUE if the list box or the item is disabled, otherwise FALSE.
//		[IN]	bIsSelected
//				TRUE if the list box item is selected, otherwise FALSE.
//		[IN]	crSuggestedColor
//				A COLORREF value containing a suggested color for the background.
//
// Return value:
//		0 (Zero)
//			Function executed successfully.
//
DWORD CListBoxST::OnDrawTextBackground(int nIndex, CDC* pDC, CRect* prcItem, CRect* prcText, BOOL bIsDisabled, BOOL bIsSelected, COLORREF crSuggestedColor)
{
	pDC->SetBkColor(crSuggestedColor);
	pDC->FillSolidRect(prcText, crSuggestedColor);

	return 0;
} // End of OnDrawTextBackground

// This function is called every time the icon of a list box item needs to be drawn.
// This is a virtual function that can be rewritten in CListBoxST-derived classes
// to produce a whole range of effects not available by default.
//
// Parameters:
//		[IN]	nIndex
//				Specifies the zero-based index of the item.
//		[IN]	pDC
//				Pointer to a CDC object that indicates the device context.
//		[IN]	prcItem
//				Pointer to a CRect object that indicates the bounds of the whole
//				list box item (icon + text).
//		[IN]	prcIcon
//				Pointer to a CRect object that indicates the bounds of the
//				area where the icon should be drawn.
//		[IN]	nImage
//				The zero-based index of the image associated with the list box item.
//		[IN]	bIsDisabled
//				TRUE if the list box or the item is disabled, otherwise FALSE.
//		[IN]	bIsSelected
//				TRUE if the list box item is selected, otherwise FALSE.
//
// Return value:
//		0 (Zero)
//			Function executed successfully.
//
DWORD CListBoxST::OnDrawIcon(int nIndex, CDC* pDC, CRect* prcItem, CRect* prcIcon, int nImage, BOOL bIsDisabled, BOOL bIsSelected)
{
	HICON	hIcon = NULL;

	hIcon = m_pImageList->ExtractIcon(nImage);
	if (hIcon)
	{
		CPoint	Point(prcIcon->left + LBST_CX_BORDER, prcIcon->top + LBST_CY_BORDER);
		CSize	Size(m_szImage);

		// Ole'!
		pDC->DrawState(	Point,
						Size, 
						hIcon,
						(bIsDisabled ? DSS_DISABLED : DSS_NORMAL), 
						(CBrush*)NULL);

		::DestroyIcon(hIcon);
	} // if

	return 0;
} // End of OnDrawIcon

BOOL CListBoxST::OnReflectedDblclk() 
{
	INT				nIndex = LB_ERR;
	BOOL			bOutside = FALSE;
	DWORD			dwPos = ::GetMessagePos();
	CPoint			Point(((int)(short)LOWORD(dwPos)), ((int)(short)HIWORD(dwPos)));

	ScreenToClient(&Point);
	nIndex = ItemFromPoint(Point, bOutside);
	if (!bOutside)	return !IsItemEnabled(nIndex);

	return FALSE;
} // End of OnReflectedDblclk

void CListBoxST::FreeResources()
{
	int	nCount = 0;

	nCount = GetCount();
	if (nCount != LB_ERR)
		for (;nCount > 0; nCount--)
		{
			DeleteItemData(nCount-1);
		} // for
} // End of FreeResources

int CListBoxST::ReplaceItemData(int nIndex, DWORD dwItemData, LPVOID pData, int nImage, DWORD dwFlags, BYTE byMask)
{
	STRUCT_LBDATA*	lpLBData = NULL;
	int				nRetValue = LB_ERR;

	// Get pointer to associated datas (if any)
	lpLBData = (STRUCT_LBDATA*)CListBox::GetItemDataPtr(nIndex);
	// If no datas exist create a new one
	if (lpLBData == NULL)
	{
		lpLBData = new STRUCT_LBDATA;
		if (lpLBData)	::ZeroMemory(lpLBData, sizeof(STRUCT_LBDATA));
	} // if

	if (lpLBData)
	{
		if ((byMask & MASK_DWDATA) == MASK_DWDATA)
			lpLBData->dwItemData = dwItemData;
		if ((byMask & MASK_LPDATA) == MASK_LPDATA)
			lpLBData->pData = pData;
		if ((byMask & MASK_NIMAGE) == MASK_NIMAGE)
			lpLBData->nImage = nImage;
		if ((byMask & MASK_DWFLAGS) == MASK_DWFLAGS)
			lpLBData->dwFlags = dwFlags;

		nRetValue = CListBox::SetItemDataPtr(nIndex, lpLBData);
	} // if

	return nRetValue;
} // End of ReplaceItemData

void CListBoxST::DeleteItemData(int nIndex)
{
	STRUCT_LBDATA*	lpLBData = NULL;

	// Get pointer to associated datas (if any)
	lpLBData = (STRUCT_LBDATA*)CListBox::GetItemDataPtr(nIndex);
	// If datas exist
		if (lpLBData != (LPVOID)-1L)	delete lpLBData;

	CListBox::SetItemDataPtr(nIndex, NULL);
} // End of DeleteItemData

// Adds a string to the list box.
//
// Parameters:
//		[IN]	lpszItem
//				Points to the null-terminated string that is to be added.
//		[IN]	nImage
//				Image to be associated with the string.
//				Pass -1L to associate no image.
//
// Return value:
//		The zero-based index of the string in the list box.
//		The return value is LB_ERR if an error occurs; the return value 
//		is LB_ERRSPACE if insufficient space is available to store the new string.
//
int CListBoxST::AddString(LPCTSTR lpszItem, int nImage)
{
	int	nIndex   = LB_ERR;

	nIndex = CListBox::AddString(lpszItem);
	if (nIndex != LB_ERR && nIndex != LB_ERRSPACE)
	{
		ReplaceItemData(nIndex, 0, NULL, nImage, 0, MASK_ALL);
	} // if

	return nIndex;
} // End of AddString

// Inserts a string at a specific location in the list box.
//
// Parameters:
//		[IN]	nIndex
//				Specifies the zero-based index of the position to insert the string.
//				If this parameter is -1, the string is added to the end of the list.
//		[IN]	lpszItem
//				Pointer to the null-terminated string that is to be inserted.
//		[IN]	nImage
//				Image to be associated with the string.
//				Pass -1L to associate no image.
//
// Return value:
//		The zero-based index of the position at which the string was inserted.
//		The return value is LB_ERR if an error occurs; the return value 
//		is LB_ERRSPACE if insufficient space is available to store the new string.
//
int CListBoxST::InsertString(int nIndex, LPCTSTR lpszString, int nImage)
{
	int	nNewIndex   = LB_ERR;

	nNewIndex = CListBox::InsertString(nIndex, lpszString);
	if (nNewIndex != LB_ERR && nNewIndex != LB_ERRSPACE)
	{
		ReplaceItemData(nNewIndex, 0, NULL, nImage, 0, MASK_ALL);
	} // if

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -