Re: CListBox::DrawItem(), CListBox::AddItem(), CListBox::SetItemData()
On Thu, 8 Nov 2007 14:43:00 +0900, "William" <port@mx15.freecom.ne.jp>
wrote:
Env: WindowsXP, VC++6.00
To have individual lines inside a CListBox to be different colors, I used
Dr. GUI's solution in [MSDN] which can be refered at "Ask Dr. GUI #43".
In the solution, the color of a line is specified by SetItemData() as
follows,
int CMyListBox::AddItem(const CString& str, COLORREF rgbText)
{
int nIndex;
nIndex = AddString(str);
if( CB_ERR != nIndex )
SetItemData(nIndex, rgbText);
return nIndex;
}
And the line is drawed by the color at the following function.
void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDC dc;
CRect rcItem(lpDIS->rcItem);
UINT nIndex = lpDIS->itemID;
COLORREF rgbBkgnd = ::GetSysColor((lpDIS->itemState & ODS_SELECTED) ?
COLOR_HIGHLIGHT : COLOR_WINDOW);
dc.Attach(lpDIS->hDC);
CBrush br(rgbBkgnd);
dc.FillRect(rcItem, &br);
if( lpDIS->itemState & ODS_FOCUS )
dc.DrawFocusRect(rcItem);
if( nIndex != (UINT)-1 )
{
// The text color is stored as the item data.
COLORREF rgbText = (lpDIS->itemState & ODS_SELECTED) ?
::GetSysColor(COLOR_HIGHLIGHTTEXT) : GetItemData(nIndex);
CString str;
GetText(nIndex, str);
dc.SetBkColor(rgbBkgnd);
dc.SetTextColor(rgbText);
dc.TextOut(rcItem.left + 2, rcItem.top + 2, str);
}
dc.Detach();
}
Obviously, the line's ItemData is used. I am tring to use line's ItemData
for other purpose. Then, how should I fix the above functions so that
ItemData is not occupied.
The itemData field is large enough to hold a pointer, so define a struct to
hold the required data and store pointers to instances of this struct.
You'll have to manage the lifetime, probably allocating with new and
overriding DeleteItem to delete the data. Note that DRAWITEMSTRUCT has an
itemData field which contains the item's data, so you don't need to call
GetItemData as you already have the data.
--
Doug Harrison
Visual C++ MVP