分享

简单的自绘CListBox(二)(多行显示,支持前景色和背景色的变更)

 学海无涯GL 2013-10-18

简单的自绘CListBox(二)(多行显示,支持前景色和背景色的变更)

简单的自绘CListBox,支持多行显示和前景色和背景色的更换。下面是相关的H头文件和CPP文件

==========================================================================================
#if !defined(AFX_MULITLINELISTBOX_H__D705CB99_9FD0_424E_BD71_027547449AE5__INCLUDED_)
#define AFX_MULITLINELISTBOX_H__D705CB99_9FD0_424E_BD71_027547449AE5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MulitLineListBox.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CMulitLineListBox window
typedef struct _LISTBOX_COLOR_
{
CString strText;
COLORREF fgColor;
COLORREF bgColor;
_LISTBOX_COLOR_()
{
strText.Empty();
fgColor = #000000;
bgColor = #ffffff;
}
}LISTBOX_COLOR, *PLISTBOX_COLOR;

class CMulitLineListBox : public CListBox
{
// Construction
public:
CMulitLineListBox();

// Attributes
public:
void AppendString(LPCSTR lpszText, COLORREF fgColor, COLORREF bgColor);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMulitLineListBox)
public:
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CMulitLineListBox();

// Generated message map functions
protected:
//{{AFX_MSG(CMulitLineListBox)
afx_msg void OnDestroy();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MULITLINELISTBOX_H__D705CB99_9FD0_424E_BD71_027547449AE5__INCLUDED_)

==============================================================================================================
// MulitLineListBox.cpp : implementation file
//

#include "stdafx.h"
#include "MulitLineListBox.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMulitLineListBox

CMulitLineListBox::CMulitLineListBox()
{
}

CMulitLineListBox::~CMulitLineListBox()
{
}


BEGIN_MESSAGE_MAP(CMulitLineListBox, CListBox)
//{{AFX_MSG_MAP(CMulitLineListBox)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMulitLineListBox message handlers
void CMulitLineListBox::AppendString(LPCSTR lpszText, COLORREF fgColor, COLORREF bgColor)
{
LISTBOX_COLOR* pInfo = new LISTBOX_COLOR;

pInfo->strText.Format(_T("%s"), lpszText);
pInfo->fgColor = fgColor; 
pInfo->bgColor = bgColor;

SetItemDataPtr(AddString(pInfo->strText), pInfo);
}

void CMulitLineListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{
// TODO: Add your code to determine the size of specified item
ASSERT(lpMeasureItemStruct->CtlType == ODT_LISTBOX);
CString strText(_T(""));
GetText(lpMeasureItemStruct->itemID, strText);
ASSERT(TRUE != strText.IsEmpty());

CRect rect;
GetItemRect(lpMeasureItemStruct->itemID, &rect);
CDC* pDC = GetDC(); 
lpMeasureItemStruct->itemHeight = pDC->DrawText(strText, -1, rect, DT_WORDBREAK | DT_CALCRECT); 
ReleaseDC(pDC);
}

void CMulitLineListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
// TODO: Add your code to draw the specified item
ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX);

LISTBOX_COLOR* pListBox = (LISTBOX_COLOR*)GetItemDataPtr(lpDrawItemStruct->itemID);
ASSERT(NULL != pListBox);

CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
// Save these value to restore them when done drawing.
COLORREF crOldTextColor = dc.GetTextColor();
COLORREF crOldBkColor = dc.GetBkColor();
// If this item is selected, set the background color 
// and the text color to appropriate values. Also, erase
// rect by filling it with the background color.
if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&
(lpDrawItemStruct->itemState & ODS_SELECTED))
{
dc.SetTextColor(pListBox->bgColor);
dc.SetBkColor(pListBox->fgColor);
dc.FillSolidRect(&lpDrawItemStruct->rcItem, pListBox->fgColor);
}
else
{
dc.SetTextColor(pListBox->fgColor);
dc.SetBkColor(pListBox->bgColor);
dc.FillSolidRect(&lpDrawItemStruct->rcItem, pListBox->bgColor);
}
lpDrawItemStruct->rcItem.left += 5;
// Draw the text.
dc.DrawText(pListBox->strText, pListBox->strText.GetLength(), &lpDrawItemStruct->rcItem, DT_WORDBREAK);
// Reset the background color and the text color back to their
// original values.
dc.SetTextColor(crOldTextColor);
dc.SetBkColor(crOldBkColor);
dc.Detach();
}


void CMulitLineListBox::OnDestroy() 
{
int nCount = GetCount();
for(int i=0; i<nCount; i++)
{
LISTBOX_COLOR* pList = (LISTBOX_COLOR*)GetItemDataPtr(i);
delete pList;
pList = NULL;
}

CListBox::OnDestroy();
// TODO: Add your message handler code here
}
===========================================================

调用方法,在主对话框类的OnInitDialog函数中加入下面的代码即可

 

CMulitLineListBox m_listBox; // 成员变量


#define IDC_LISTBOX 0x11

CRect rc;

GetClientRect(&rc);

rc.bottom -= 35;

rc.DeflateRect(CSize(10, 10));

m_listBox.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL |

LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS, rc, this, IDC_LISTBOX);

CString strText(_T(""));

COLORREF fgColor;

COLORREF bgColor;

for(int i=0; i<20; i++)

{

if(i%2)

strText = _T("Hello, World!");

else

strText = _T("Hello, World!/r/nHello, World!");

fgColor = RGB(128, 0, i*7%128);

bgColor = RGB(0, i*7%128, 0);

m_listBox.AppendString(strText, fgColor, bgColor);

}


 

显示的效果图如下所示:

 


 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多