Knowledge Base Nr: 00174 OwnerDrawListBox2.cpp - http://www.swe-kaiser.de

Downloads: C++-Klassen

MFC: Ownerdraw Listbox (mehrzeiligen Items, verschiedenfarbige Texte, verschiedene Fonts)
ModifyString()-Funktion für flackerfreies Update (z.B. Uhrzeit anzeigen)

  
//in h-File der Dialog-Klasse CListBox ersetzen durch COwnerDrawListBox2
//
// Resource: Property settings:
// ------------------
// Has Strings = Yes
// Owner Draw = variable
// Want key input = Yes
// No integral height = YES
// Notify = YES

class COwnerDrawListBox2 : public CListBox
{
protected:
CStringArray m_arHead;
CStringArray m_arItems;
CDWordArray m_arCref;
CWordArray m_arX;
CWordArray m_arY;
CWordArray m_arFSize;

int m_nMaxHeight;
COLORREF m_crBackground;
COLORREF m_crSelection;

virtual BOOL FormatAndDrawItem(CDC *pDC, int nIndex, LPRECT lpRect, bool bSelected);
virtual BOOL FormatAndDrawString(CDC *pDC, LPCTSTR lpszStr, LPRECT lpRect, bool bSelected);

public:
COwnerDrawListBox2();
virtual ~COwnerDrawListBox2();

void Settings(int nMaxHeight
, COLORREF crBackground = RGB(88,88,88)
, COLORREF crSelection = RGB(33,33,33));

//customize the items
void ResetInfo();
void AddItemInfo(LPCSTR lpszHead, COLORREF cref, WORD nX, WORD nY, int nFontSize = 8);

//handle items
int InsertString(int nIndex, LPCTSTR lpszItem);
int AddString( LPCTSTR lpszItem );
int ModifyString(int nIndex, LPCTSTR lpszItem);
int DeleteString(int nIndex);
void ResetContent();

//manage entries
int LoadFromFile(LPCSTR fileName); //0 = success
void Clone(COwnerDrawListBox2* pSource, BOOL bInsertHeader);


// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COwnerDrawListBox2)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct);
virtual void DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
//}}AFX_VIRTUAL
...
};


void COwnerDrawListBox2::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
//TRACE("id:%d action:%x state:%x \n", lpDIS->itemID, lpDIS->itemAction, lpDIS->itemState);
if (lpDIS->itemID < 0)
return;

CDC *pDC = CDC::FromHandle(lpDIS->hDC);

enum DRAWMODES {M_NONE, M_NORMAL, M_SELECTED } nDrawMode = M_NONE;

if (lpDIS->itemAction & ODA_DRAWENTIRE)
nDrawMode = M_NORMAL;

if (!(lpDIS->itemState & ODS_SELECTED) &&
(lpDIS->itemAction & ODA_SELECT))
nDrawMode = M_NORMAL;

if ((lpDIS->itemState & ODS_SELECTED) &&
(lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
nDrawMode = M_SELECTED;

LPRECT lpRect = &(lpDIS->rcItem);

CBrush brush;

switch(nDrawMode)
{
case M_NORMAL:
//pDC->BitBlt(0, lpRect->top, lpRect->right, lpRect->bottom-lpRect->top, NULL, 0, 0, WHITENESS); // DSTINVERT);
brush.CreateSolidBrush(m_crBackground);
pDC->FillRect(lpRect, &brush);
break;

case M_SELECTED: //show selection as rectangle
//pDC->Rectangle(lpRect->left+1, lpRect->top+1, lpRect->right-1, lpRect->bottom-1);
//pDC->BitBlt(0, lpRect->top, lpRect->right, lpRect->bottom-lpRect->top, NULL, 0, 0, BLACKNESS); // DSTINVERT);
brush.CreateSolidBrush(m_crSelection);
pDC->FillRect(lpRect, &brush);
break;
}

if (nDrawMode != M_NONE)
{
BOOL bSucc = FormatAndDrawItem(pDC, lpDIS->itemID, lpRect, (nDrawMode == M_SELECTED));
ASSERT(bSucc);
}

if ((lpDIS->itemState & ODS_FOCUS) || (lpDIS->itemAction & ODA_FOCUS))
{
// Item has got the focus
pDC->DrawFocusRect(lpRect);

/*
brush.CreateSolidBrush(RGB(0,255,0));

int nBorder = 3;
CRect rect;

rect.SetRect(lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
pDC->FillRect(&rect, &brush);
*/
}
}


BOOL COwnerDrawListBox2::FormatAndDrawString(CDC *pDC, LPCTSTR lpszStr, LPRECT lpRect, bool bSelected)
{
CString str(lpszStr);

int nPart = 0;
CString strPart;

int nMinSize = m_arHead.GetSize();

while (nPart < nMinSize)
{
int nPos = str.Find('\t');

if (nPos >= 0)
strPart = str.Left(nPos);
else
strPart = str;

int x = m_arX[nPart];
int y = m_arY[nPart] + ROWOFFSET;
ASSERT(m_arY[nPart] <= m_nMaxHeight);

int nFSize = m_arFSize[nPart];;
CFont font;
font.CreatePointFont(nFSize*10, "Times New Roman");

pDC->SelectObject(&font);
if (bSelected)
pDC->SetBkColor(m_crSelection);
else
pDC->SetBkColor(m_crBackground);
pDC->SetTextColor(m_arCref[nPart]);
pDC->ExtTextOut(x, // x-coordinate of reference point
lpRect->top + y, // y-coordinate of reference point
ETO_CLIPPED , // ETO_CLIPPED | ETO_OPAQUE, // text-output options
lpRect, // optional clipping and/or opaquing rectangle
strPart, // points to string
NULL ); // pointer to array of intercharacter spacing values

if (nPos < 0)
break;

str = str.Mid(nPos+1);
nPart++;
ASSERT(nPart < nMinSize+1);
}

return TRUE;
}

BOOL COwnerDrawListBox2::FormatAndDrawItem(CDC *pDC, int nIndex, LPRECT lpRect, bool bSelected)
{
CString str;

//GetText(nIndex, str);
str = m_arItems.GetAt(nIndex);

BOOL bSucc = FormatAndDrawString(pDC, str, lpRect, bSelected);

return bSucc;
}