Knowledge Base Nr: 00174 OwnerDrawListBox2.cpp - http://www.swe-kaiser.de
Downloads:
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;
}