www.pudn.com > CListBoxColorPickerST_demo.zip > ListBoxColorPickerST.cpp


#include "stdafx.h" 
#include "ListBoxColorPickerST.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_CRCOLOR	0x04	// crColor is valid 
#define MASK_ALL		0xff	// All fields are valid 
 
CListBoxColorPickerST::CListBoxColorPickerST() 
{ 
} 
 
CListBoxColorPickerST::~CListBoxColorPickerST() 
{ 
} 
 
void DDX_ListBoxColorPickerST(CDataExchange *pDX, int nIDC, COLORREF& rgbColor) 
{ 
	HWND hWndCtrl = pDX->PrepareCtrl( nIDC ); 
	ASSERT( hWndCtrl ); 
 
	CListBoxColorPickerST *pPicker = (CListBoxColorPickerST*)CWnd::FromHandle(hWndCtrl); 
	ASSERT( pPicker ); 
 
	// Only support getting of color 
	if(pDX->m_bSaveAndValidate) 
	{ 
		rgbColor = pPicker->GetSelectedColor(); 
	} 
} // End of DDX_ListBoxColorPickerST 
 
BEGIN_MESSAGE_MAP(CListBoxColorPickerST, CListBox) 
	//{{AFX_MSG_MAP(CListBoxColorPickerST) 
	ON_WM_DESTROY() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
void CListBoxColorPickerST::OnDestroy()  
{ 
	FreeResources(); 
	CListBox::OnDestroy(); 
} // End of OnDestroy 
 
void CListBoxColorPickerST::DrawItem(LPDRAWITEMSTRUCT pDIStruct) 
{ 
	CString			strColour; 
	CDC				dcContext; 
	CRect			rItemRect(pDIStruct->rcItem); 
	CRect			rBlockRect(rItemRect); 
	CRect			rTextRect(rBlockRect); 
	CBrush			brFrameBrush; 
	int				iFourthWidth = 0; 
	int				iItem = pDIStruct->itemID; 
	int				iAction = pDIStruct->itemAction; 
	int				iState = pDIStruct->itemState; 
	COLORREF		crColour = NULL; 
	COLORREF		crNormal = GetSysColor( COLOR_WINDOW ); 
	COLORREF		crSelected = GetSysColor( COLOR_HIGHLIGHT ); 
	COLORREF		crText = GetSysColor( COLOR_WINDOWTEXT ); 
	STRUCT_LBDATA*	lpLBData = NULL; 
 
	if( !dcContext.Attach( pDIStruct->hDC ) ) 
	{ 
		return; 
	} 
 
	iFourthWidth = ( rBlockRect.Width() / 4 ); 
	brFrameBrush.CreateStockObject( BLACK_BRUSH ); 
 
	if( iState & ODS_SELECTED ) 
	{ 
		dcContext.SetTextColor(	( 0x00FFFFFF & ~( crText ) ) ); 
		dcContext.SetBkColor( crSelected ); 
		dcContext.FillSolidRect( &rBlockRect, crSelected ); 
	} 
	else 
	{ 
		dcContext.SetTextColor( crText ); 
		dcContext.SetBkColor( crNormal ); 
		dcContext.FillSolidRect( &rBlockRect, crNormal ); 
	} 
 
	if( iState & ODS_FOCUS ) 
	{ 
		dcContext.DrawFocusRect( &rItemRect ); 
	} 
 
	// calculate text area. 
	rTextRect.left += ( iFourthWidth + 2 ); 
	rTextRect.top += 2; 
 
	// calculate colour block area. 
	rBlockRect.DeflateRect( CSize( 2, 2 ) ); 
	rBlockRect.right = iFourthWidth; 
 
	// draw colour text and block. 
	if( iItem != -1 ) 
	{ 
		CListBox::GetText(iItem, strColour); 
 
		if( iState & ODS_DISABLED ) 
		{ 
			crColour = GetSysColor( COLOR_INACTIVECAPTIONTEXT ); 
			dcContext.SetTextColor( crColour ); 
		} 
		else 
		{ 
			crColour = GetColor(iItem); 
		} 
 
		dcContext.SetBkMode( TRANSPARENT ); 
		dcContext.TextOut( rTextRect.left, rTextRect.top,	strColour ); 
 
		dcContext.FillSolidRect( &rBlockRect, crColour ); 
				 
		dcContext.FrameRect( &rBlockRect, &brFrameBrush ); 
	} 
 
	dcContext.Detach(); 
} 
 
void CListBoxColorPickerST::FreeResources() 
{ 
	int	nCount = 0; 
 
	nCount = GetCount(); 
	if (nCount != LB_ERR) 
		for (;nCount > 0; nCount--) 
		{ 
			DeleteItemData(nCount-1); 
		} // for 
} // End of FreeResources 
 
int CListBoxColorPickerST::ReplaceItemData(int nIndex, DWORD dwItemData, LPVOID pData, COLORREF crColor, 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_CRCOLOR) == MASK_CRCOLOR) 
			lpLBData->crColor = crColor; 
 
		nRetValue = CListBox::SetItemDataPtr(nIndex, lpLBData); 
	} // if 
 
	return nRetValue; 
} // End of ReplaceItemData 
 
void CListBoxColorPickerST::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]	crColor 
//				Color to be associated with the string. 
// 
// 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 CListBoxColorPickerST::AddString(LPCTSTR lpszItem, COLORREF crColor) 
{ 
	int	nIndex   = LB_ERR; 
 
	nIndex = CListBox::AddString(lpszItem); 
	if (nIndex != LB_ERR && nIndex != LB_ERRSPACE) 
	{ 
		ReplaceItemData(nIndex, 0, NULL, crColor, 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]	crColor 
//				Color to be associated with the string. 
// 
// 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 CListBoxColorPickerST::InsertString(int nIndex, LPCTSTR lpszString, COLORREF crColor) 
{ 
	int	nNewIndex   = LB_ERR; 
 
	nNewIndex = CListBox::InsertString(nIndex, lpszString); 
	if (nNewIndex != LB_ERR && nNewIndex != LB_ERRSPACE) 
	{ 
		ReplaceItemData(nNewIndex, 0, NULL, crColor, MASK_ALL); 
	} // if 
 
	return nNewIndex; 
} // End of InsertString 
 
// Deletes a string from the list box. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the string to be deleted. 
// 
// Return value: 
//		A count of the strings remaining in the list box. 
//		The return value is LB_ERR if nIndex specifies an index greater than  
//		the number of items in the list. 
// 
int CListBoxColorPickerST::DeleteString(int nIndex) 
{ 
	int	nRetValue = LB_ERR; 
 
	DeleteItemData(nIndex); 
	nRetValue = CListBox::DeleteString(nIndex); 
 
	return nRetValue; 
} // End of DeleteString 
 
// Replaces a string at a specific location in the list box. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the position to replace the string. 
//		[IN]	lpszItem 
//				Pointer to the null-terminated string that is to be replaced. 
//		[IN]	crColor 
//				Color to be associated with the string. 
// 
// Return value: 
//		The zero-based index of the position at which the string was replaced. 
//		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 CListBoxColorPickerST::ReplaceString(int nIndex, LPCTSTR lpszString, COLORREF crColor) 
{ 
	int	nRetValue; 
 
	nRetValue = DeleteString(nIndex); 
	if (nRetValue != LB_ERR) 
	{ 
		nRetValue = InsertString(nIndex, lpszString, crColor); 
	} // if 
 
	return nRetValue; 
} // End of ReplaceString 
 
// Clears all the entries from the list box. 
// 
void CListBoxColorPickerST::ResetContent() 
{ 
	FreeResources(); 
	CListBox::ResetContent(); 
} // End of ResetContent 
 
// Associates a color with a string at a specific location in the list box. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the string. 
//		[IN]	crColor 
//				Color to be associated with the string. 
//		[IN]	bRepaint 
//				If TRUE the control will be repainted. 
// 
// Return value: 
//		LB_ERR if an error occurs. 
// 
int CListBoxColorPickerST::SetColor(int nIndex, COLORREF crColor, BOOL bRepaint) 
{ 
	COLORREF	crOldColor; 
	int			nRetValue = LB_ERR; 
 
	crOldColor = GetColor(nIndex); 
	if (crColor != crOldColor) 
	{ 
		nRetValue = ReplaceItemData(nIndex, 0, NULL, crColor, MASK_CRCOLOR); 
		if (bRepaint)	Invalidate(); 
	} // if 
 
	return nRetValue; 
} // End of SetColor 
 
// Returns the color associated with a string at a specific location in the list box. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the color to be retrieved. 
// 
// Return value: 
//		The color associated with the specified string. 
//		The return value is -1 if an error occurs. 
// 
COLORREF CListBoxColorPickerST::GetColor(int nIndex) 
{ 
	STRUCT_LBDATA*	lpLBData = NULL; 
 
	lpLBData = (STRUCT_LBDATA*)CListBox::GetItemData(nIndex); 
	if (lpLBData != (LPVOID)-1L) 
		return lpLBData->crColor; 
 
	return -1L; 
} // End of GetColor 
 
// Returns the color associated with the currently selected string in the list box. 
// 
// Return value: 
//		The color associated with the currently selected string. 
//		The return value is -1 if an error occurs or no string is selected. 
// 
COLORREF CListBoxColorPickerST::GetSelectedColor() 
{ 
	return GetColor(GetCurSel()); 
} // End of GetSelectedColor 
 
// Sets the 32-bit value associated with the list box item. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the item. 
//		[IN]	dwItemData 
//				Specifies the value to be associated with the item. 
// 
// Return value: 
//		LB_ERR if an error occurs. 
// 
int CListBoxColorPickerST::SetItemData(int nIndex, DWORD dwItemData) 
{ 
	return ReplaceItemData(nIndex, dwItemData, NULL, 0, MASK_DWDATA); 
} // End of SetItemData 
 
// Returns the 32-bit value associated with the list box item. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the item. 
// 
// Return value: 
//		The 32-bit value associated with the item, or LB_ERR if an error occurs. 
// 
DWORD CListBoxColorPickerST::GetItemData(int nIndex) 
{ 
	STRUCT_LBDATA*	lpLBData = NULL; 
 
	lpLBData = (STRUCT_LBDATA*)CListBox::GetItemDataPtr(nIndex); 
	if (lpLBData != (LPVOID)-1L) 
		return lpLBData->dwItemData; 
 
	return LB_ERR; 
} // End of GetItemData 
 
// Sets a pointer to a list box item. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the item. 
//		[IN]	pData 
//				Specifies the pointer to be associated with the item. 
// 
// Return value: 
//		LB_ERR if an error occurs. 
// 
int CListBoxColorPickerST::SetItemDataPtr(int nIndex, void* pData) 
{ 
	return ReplaceItemData(nIndex, 0, pData, 0, MASK_LPDATA); 
} // End of SetItemDataPtr 
 
// Returns a pointer of a list box item. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the item. 
// 
// Return value: 
//		Pointer associated with the item, or -1 if an error occurs. 
// 
void* CListBoxColorPickerST::GetItemDataPtr(int nIndex) 
{ 
	STRUCT_LBDATA*	lpLBData = NULL; 
 
	lpLBData = (STRUCT_LBDATA*)CListBox::GetItemDataPtr(nIndex); 
	if (lpLBData != (LPVOID)-1L) 
		return lpLBData->pData; 
 
	return (LPVOID)-1L; 
} // End of GetItemDataPtr 
 
// Searches for a particular color in the list box. If found the associated 
// string is then selected. The search ends at the first occurence of the color. 
// 
// Parameters: 
//		[IN]	crColor 
//				Color to search for. 
// 
// Return value: 
//		The zero-based index of the position at which the color was found. 
//		The return value is LB_ERR if an error occurs or the spcified color 
//		is not found. 
// 
int CListBoxColorPickerST::SelectColor(COLORREF crColor) 
{ 
	int	nCount = 0; 
	int	nLoop = 0; 
 
	// Search all the listbox 
	nCount = GetCount(); 
	if (nCount != LB_ERR) 
		for (nLoop = 0; nLoop < nCount; nLoop++) 
		{ 
			// If color is found 
			if (crColor == GetColor(nLoop))	 
			{ 
				SetCurSel(nLoop); 
				return nLoop; 
			} // if 
		} // for 
 
	return LB_ERR; 
} // End of SelectColor 
 
// Returns a list box item and the associated color. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the item. 
//		[OUT]	lpszBuffer 
//				Pointer to the buffer that will receive the string. 
//				The buffer must have sufficient space for the string and a  
//				terminating null character. The size of the string can be  
//				determined ahead of time by calling the GetTextLen member function. 
//		[OUT]	lpcrColor 
//				Pointer to a COLORREF variable that will receive the color associated with 
//				the specified item. 
// 
// Return value: 
//		The length (in bytes) of the string, excluding the terminating null character.  
//		If nIndex does not specify a valid index, the return value is LB_ERR. 
// 
int CListBoxColorPickerST::GetTextAndColor(int nIndex, LPTSTR lpszBuffer, COLORREF* lpcrColor) 
{ 
	COLORREF	crColor; 
 
	// Get color 
	crColor = GetColor(nIndex); 
	if (crColor != -1L) 
	{ 
		*lpcrColor = crColor; 
		// Call base-class method 
		return CListBox::GetText(nIndex, lpszBuffer); 
	} // if 
 
	return LB_ERR; 
} // End of GetTextAndColor 
 
// Returns a list box item and the associated color. 
// 
// Parameters: 
//		[IN]	nIndex 
//				Specifies the zero-based index of the item. 
//		[OUT]	rString 
//				A reference to a CString object. 
//		[OUT]	lpcrColor 
//				Pointer to a COLORREF variable that will receive the color associated with 
//				the specified item. 
// 
// Return value: 
//		The length (in bytes) of the string, excluding the terminating null character.  
//		If nIndex does not specify a valid index, the return value is LB_ERR. 
// 
int CListBoxColorPickerST::GetTextAndColor(int nIndex, CString &rString, COLORREF* lpcrColor) 
{ 
	COLORREF	crColor; 
 
	// Get color 
	crColor = GetColor(nIndex); 
	if (crColor != -1L) 
	{ 
		*lpcrColor = crColor; 
		// Call base-class method 
		CListBox::GetText(nIndex, rString); 
		return rString.GetLength(); 
	} // if 
 
	return LB_ERR; 
} // End of GetTextAndColor 
 
#undef	MASK_DWDATA 
#undef	MASK_LPDATA 
#undef	MASK_CRCOLOR 
#undef	MASK_ALL