To make a ListBox in WTL display colored texts you need to handle CustomDraw message.
Program to specify the color of individual list item according to some condition.
//ListViewCtrlEx.h
class CListViewCtrlEx: public CWindowImpl<CListViewCtrlEx, CListViewCtrl>, public CCustomDraw<CListViewCtrlEx>
{
public:
BEGIN_MSG_MAP(CListViewCtrlEx)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
CHAIN_MSG_MAP_ALT(CCustomDraw<CListViewCtrlEx>, 1)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bHandled);
DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw);
DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw);
void ForceMeasureItemMessage();
void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/);
BOOL DeleteItem(int nItem);
void GetCellRect(int header_column, const CRect& item_rect, CRect& cell_rect);
};
//ListViewCtrlEx.cpp
LRESULT CListViewCtrlEx::OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bHandled)
{
HDC hdc = (HDC)wParam;
RECT rcClient ;
GetClientRect(&rcClient);
HBRUSH hBkBrush = CreateSolidBrush(RGB(255,255,255));
FillRect(hdc, &rcClient, hBkBrush);
return 1;
}
DWORD CListViewCtrlEx::OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
{
return CDRF_NOTIFYITEMDRAW;
}
DWORD CListViewCtrlEx::OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( lpNMCustomDraw );
COLORREF crText = RGB(0,0,0);
int itemid = (pLVCD->nmcd).dwItemSpec; //this is item id
if(GetItemData(itemid) == 1)
{
crText = RGB(255,0,0);
}
else
{
crText = RGB(0,0,0);
}
// Store the color back in the NMLVCUSTOMDRAW struct.
COLORREF crTextBk = RGB(255,255,255);
pLVCD->clrTextBk = crTextBk;
pLVCD->clrText = crText;
CDCHandle dc = pLVCD->nmcd.hdc;
// Tell Windows to paint the control itself.
return CDRF_DODEFAULT;
}
void CListViewCtrlEx::ForceMeasureItemMessage()
{
// I just want to nudge it up a little.
CRect window_rect;
GetWindowRect(&window_rect);
CPoint pt = window_rect.TopLeft();
::ScreenToClient(GetParent(), &pt);
window_rect.right = pt.x + window_rect.Width();
window_rect.left = pt.x;
window_rect.bottom = pt.y + window_rect.Height();
window_rect.top = pt.y + 1;
MoveWindow(window_rect);
// Alright now move it back.
window_rect.top = pt.y;
MoveWindow(window_rect);
}
void CListViewCtrlEx::DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/)
{
};
BOOL CListViewCtrlEx::DeleteItem(int nItem)
{
ATLASSERT(::IsWindow(m_hWnd));
return (BOOL)::SendMessage(m_hWnd, LVM_DELETEITEM, nItem, 0L);
}
void CListViewCtrlEx::GetCellRect(int header_column, const CRect& item_rect, CRect& cell_rect)
{
CHeaderCtrl header = GetHeader();
CRect header_rect;
header.GetItemRect(header_column, &header_rect);
// If we don't do this, when we scroll to the right, we will be
// drawing as if we weren't and your cells won't line up with the
// columns.
int x_offset = -GetScrollPos(SB_HORZ);
cell_rect.left = x_offset + header_rect.left;
cell_rect.right = x_offset + header_rect.right;
cell_rect.top = item_rect.top;
cell_rect.bottom = item_rect.bottom;
}
No comments:
Post a Comment