Change the background color of individual columns


To set the background color of a column, the list view control has to be owner drawn. In an owner drawn control, each row is drawn by the application program rather than by the control. So when drawing a row, the background color can be set to our choice within the rectangle occupied by a particular column. To implement an owner drawn control see the topic 'Selection highlighting of entire row'.

The code segment below illustrates how to set yellow as the background color for alternate columns. The code shown is part of the DrawItem() function. The first segment draws the background color just before drawing the state icon. The second segment draws the background color within the loop that draws the labels for the remaining columns.

	// Set clip region
	rcCol.right = rcCol.left + GetColumnWidth(0);
	CRgn rgn;
	rgn.CreateRectRgnIndirect(&rcCol);
	pDC->SelectClipRgn(&rgn);
	rgn.DeleteObject();

	// Draw column background
	if( !bHighlight )
		pDC->FillRect(rcCol, &CBrush(RGB(255,255,0)));

	// Draw state icon
	if (lvi.state & LVIS_STATEIMAGEMASK)

	:
	:
	:
	:
				   
	for(int nColumn = 1; GetColumn(nColumn, &lvc); nColumn++)
	{
		rcCol.left = rcCol.right;
		rcCol.right += lvc.cx;

		// Draw column background
		if( !bHighlight || ( bHighlight && m_nHighlight == HIGHLIGHT_NORMAL ) )
			if( (nColumn+1) % 2 )
				pDC->FillRect(rcCol, &CBrush(RGB(255,255,0)));


 



Comments

  • Doesn't work - Brush clears text

    Posted by Legacy on 09/13/2001 12:00am

    Originally posted by: Bill Munro


    Fillrect causes the brush to clear any text already initialized via SetItemText in OnInitialUpdate. I tried SetBkColor, and that did not work either. The NM_CUSTOMDRAW solution posted elsewhere on this site did not work either, because I am using VC5, which does not seem to have Subitem access in its version of COMMCTRL.H. Any suggestions??

    Reply
  • Using NM_CUSTOMDRAW to change text and backgrond colours in a listview

    Posted by Legacy on 04/19/2000 12:00am

    Originally posted by: Brad Spencer

    Philip Lee is right that you can use NM_CUSTOMDRAW to change items an sub items text colour and background colour.
    
    Below is an example of how to do this in MFC.

    1: To trap the NM_CUSTOMDRAW draw message add
    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) to the message map in the listview .cpp file and
    afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult); before you DECLARE_MESSAGE_MAP() in the .h file.
    These lines of cod have to be added by hand, they can not be found through class wizard.

    2: Trap the type of custom draw message in the OnCustomDraw function.
    The example below changes colour of both text and background for items and sub items.

    void CColourListView::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
    {
    *pResult = 0;

    COLORREF dwColourTxt = 0;
    COLORREF dwColourBk = RGB(255, 255, 255);

    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;

    switch(lplvcd->nmcd.dwDrawStage)
    {
    case CDDS_PREPAINT :
    {
    *pResult = CDRF_NOTIFYITEMDRAW;
    return;
    }

    // Modify item text and or background
    case CDDS_ITEMPREPAINT:
    {
    if(lplvcd->nmcd.dwItemSpec == 0)
    {
    dwColourTxt = RGB(255, 0, 0); // Red
    }
    else if(lplvcd->nmcd.dwItemSpec == 1)
    {
    dwColourTxt = RGB(0, 255, 0); // Green
    }
    else
    {
    dwColourTxt = RGB(0, 0, 255); // Blue
    }
    lplvcd->clrText = dwColourTxt;
    // If you want the sub items the same as the item set *pResult
    // to CDRF_NEWFONT
    *pResult = CDRF_NOTIFYSUBITEMDRAW;
    return;
    }

    // Modify sub item text and or background
    case CDDS_SUBITEM | CDDS_PREPAINT | CDDS_ITEM:
    {
    // Ignore the first sub item it is the item handled above
    if(lplvcd->iSubItem != 0)
    {
    // First sub item
    if(lplvcd->iSubItem == 1)
    {
    dwColourTxt = RGB(0, 127, 127); // Pale blue
    dwColourBk = RGB(255, 255, 255); // White
    }
    // All sub items after the first
    else
    {
    dwColourTxt = RGB(255, 255, 255); // White
    if(lplvcd->nmcd.dwItemSpec == 0)
    {
    dwColourBk = RGB(255, 0, 0); // Red
    }
    else if(lplvcd->nmcd.dwItemSpec == 1)
    {
    dwColourBk = RGB(0, 255, 0); // Green
    }
    else
    {
    dwColourBk = RGB(0, 0, 255); // Blue
    }
    }
    lplvcd->clrText = dwColourTxt;
    lplvcd->clrTextBk = dwColourBk;
    }
    *pResult = CDRF_NEWFONT;
    return;
    }
    }
    }

    This method means you do not have to make your control owner drawn.

    Reply
  • It doesn't work!

    Posted by Legacy on 08/06/1999 12:00am

    Originally posted by: Nicola Genchi

    Hello! I am sorry, but it doesn't work! For sure I am making some mistakes! I wrote down all the code of selecting a row and the remainig code for the colouring of the columns but it doesn't work!!!
    
    I am working with Visual C++ 6.0
    I am using this sentence for my list controls :

    m_cDetailOrderList.SetExtendedStyle(LVS_EX_FULLROWSELECT |
    LVS_EX_ONECLICKACTIVATE |
    LVS_EX_UNDERLINEHOT |
    LVS_EX_GRIDLINES |
    LVS_EX_HEADERDRAGDROP);

    It solves the problem of the full selection...
    Maybe I have to use different kind of code?

    Please help me! Thank you

    Nicola

    Reply
  • Custom Draw

    Posted by Legacy on 03/25/1999 12:00am

    Originally posted by: Philip Lee

    Setting the text color/background color and font of individual rows and/or sub-items can be done without full owner draw by using custom draw.

    Sorry I haven't got an example at the moment but look in the platform SDK under NM_CUSTOMDRAW.

    Reply
  • Change text color for highlighted columns

    Posted by Legacy on 01/18/1999 12:00am

    Originally posted by: Hoyle Greene

    I am having trouble dtermining if the text color can be changed for individual columns of a row. Help?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Packaged application development teams frequently operate with limited testing environments due to time and labor constraints. By virtualizing the entire application stack, packaged application development teams can deliver business results faster, at higher quality, and with lower risk.

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds