Amit
Amit

Reputation: 703

ListView Item background

I want to mark a special line in the listview with a color, so it'll look like this : http://www.codeproject.com/KB/list/CColorListCtrl/rowCell.jpg (The first row - which is green).

Im not sure how exactly do I do this, and got a bit confused by the results on the network... So how can I do it?

Thanks!

Upvotes: 5

Views: 5060

Answers (1)

Eejin
Eejin

Reputation: 840

From Codeproject

First we handle the WM_NOTIFY message to use a NM_CUSTOMDRAW notification. We don't need to use any owner drawn listview, and since this is custom drawn, we can paint the items/subitems at our will.

if(((LPNMHDR)lParam)->code == NM_CUSTOMDRAW) {
    SetWindowLong(hWnd, DWL_MSGRESULT, 
    (LONG)ProcessCustomDraw(lParam));
    return TRUE;
}

-

LRESULT ProcessCustomDraw (LPARAM lParam) {
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
switch(lplvcd->nmcd.dwDrawStage) 
{
    case CDDS_PREPAINT : //Before the paint cycle begins
        //request notifications for individual listview items
        return CDRF_NOTIFYITEMDRAW;

    case CDDS_ITEMPREPAINT: //Before an item is drawn
        if (((int)lplvcd->nmcd.dwItemSpec%2)==0)
        {
            //customize item appearance
            lplvcd->clrText   = RGB(255,0,0);
            lplvcd->clrTextBk = RGB(200,200,200);
            return CDRF_NEWFONT;
        }
        else{
            lplvcd->clrText   = RGB(0,0,255);
            lplvcd->clrTextBk = RGB(255,255,255);

            return CDRF_NEWFONT;
        }
        break;

    //Before a subitem is drawn
    case CDDS_SUBITEM | CDDS_ITEMPREPAINT: 
        if (iSelect == (int)lplvcd->nmcd.dwItemSpec)
        {
            if (0 == lplvcd->iSubItem)
            {
                //customize subitem appearance for column 0
                lplvcd->clrText   = RGB(255,0,0);
                lplvcd->clrTextBk = RGB(255,255,255);

                //To set a custom font:
                //SelectObject(lplvcd->nmcd.hdc, 
                //    <your custom HFONT>);

                return CDRF_NEWFONT;
            }
            else if (1 == lplvcd->iSubItem)
            {
                //customize subitem appearance for columns 1..n
                //Note: setting for column i 
                //carries over to columnn i+1 unless
                //      it is explicitly reset
                lplvcd->clrTextBk = RGB(255,0,0);
                lplvcd->clrTextBk = RGB(255,255,255);

                return CDRF_NEWFONT;
            }
        }
    }
    return CDRF_DODEFAULT;
}

EDIT

Well, I went ahead and made a small example. It might be a bit dirty but it works. You just need to fill in some of your own variables, but it works.

LRESULT MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
    case WM_CREATE: 
        {
            //Initialise something
            INITCOMMONCONTROLSEX icex; //Hehehe
            icex.dwICC = ICC_LISTVIEW_CLASSES;
            InitCommonControlsEx(&icex);

            //Add listview
            listview = CreateWindow(WC_LISTVIEW, 
                                        "LISTVIEW",
                                         WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT,
                                         0, 0,
                                         400,
                                         400,
                                         hWnd,
                                         0,
                                         hInstance,
                                         NULL);

            ListView_SetExtendedListViewStyle(listview, LVS_EX_FULLROWSELECT);

            //Add column
            LVCOLUMN lvc;
            lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
            lvc.iSubItem = 0;
            lvc.pszText = (char*) "test";
            lvc.cx = 200; 
            lvc.fmt = LVCFMT_RIGHT;
            ListView_InsertColumn(listview, 0, &lvc);
            ListView_InsertColumn(listview, 0, &lvc);

            //Add item
            LVITEM lvI;
            lvI.pszText   = (char*) "item";
            lvI.mask      = LVIF_TEXT;
            lvI.stateMask = 0;
            lvI.iSubItem  = 0;
            lvI.iItem  = 0;
            ListView_InsertItem(listview, &lvI);

            lvI.iSubItem  = 1;
            lvI.pszText   = (char*) "subitem";
            ListView_SetItem(listview, &lvI);

            //Add item
            lvI.pszText   = (char*) "item";
            lvI.mask      = LVIF_TEXT;
            lvI.stateMask = 0;
            lvI.iSubItem  = 0;
            lvI.iItem  = 1;
            ListView_InsertItem(listview, &lvI);

            lvI.iSubItem  = 1;
            lvI.pszText   = (char*) "subitem";
            ListView_SetItem(listview, &lvI);
        }
    break;
    case WM_CLOSE:  
        DestroyWindow(hWnd);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        running = false;
        return 0;
    case WM_COMMAND:
        switch(LOWORD(wParam)) {
        }
    break;
    case WM_NOTIFY:
        if(((LPNMHDR)lParam)->code == NM_CUSTOMDRAW) {
                LPNMLVCUSTOMDRAW  lplvcd = (LPNMLVCUSTOMDRAW)lParam;
                switch(lplvcd->nmcd.dwDrawStage) {
                    case CDDS_PREPAINT:
                        return CDRF_NOTIFYITEMDRAW;
                    break;
                    case CDDS_ITEMPREPAINT:
                        if (((int)lplvcd->nmcd.dwItemSpec%2)==0) {
                            lplvcd->clrText   = RGB(0,0,0);
                            lplvcd->clrTextBk = RGB(255,0,0);
                        } else {
                            lplvcd->clrText   = RGB(0,0,255);
                            lplvcd->clrTextBk = RGB(255,255,255);
                        }
                        return CDRF_NEWFONT;
                    break;
                    //There would be some bits here for subitem drawing but they don't seem neccesary as you seem to want a full row color only
                    case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
                        return CDRF_NEWFONT;    
                    break;
                }


                return TRUE;
        }
    default:
        return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return 0;
}

Upvotes: 8

Related Questions