【问题标题】:ListView Item backgroundListView 项目背景
【发布时间】:2014-06-20 07:04:52
【问题描述】:

我想用颜色标记列表视图中的特殊行,所以它看起来像这样: http://www.codeproject.com/KB/list/CColorListCtrl/rowCell.jpg (第一行 - 绿色)。

我不确定我究竟是如何做到这一点的,并且对网络上的结果有点困惑...... 那我该怎么做呢?

谢谢!

【问题讨论】:

    标签: c++ listview winapi win32gui


    【解决方案1】:

    来自Codeproject

    首先我们处理 WM_NOTIFY 消息以使用 NM_CUSTOMDRAW 通知。我们不需要使用任何所有者绘制的列表视图,并且由于这是自定义绘制的,我们可以随意绘制项目/子项目。

    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;
    }
    

    编辑

    好吧,我继续做了一个小例子。它可能有点脏,但它有效。你只需要填写一些你自己的变量,但它可以工作。

    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;
    }
    

    【讨论】:

    • 谢谢!但是,iSelect 是在列表视图中选择的索引吗?另外,我不明白如何使用此代码开始在 listView 项目上绘画。我已经在代码的顶部添加了 if 语句,尽管它没有进入其中......
    • 好像是选中项:iSelect=SendMessage(hList,LVM_GETNEXTITEM, -1,LVNI_FOCUSED); // return item selected 你把它放在你的事件循环中了吗?
    • 那我把if语句放在哪里,问是不是NM_CUSTOMDRAW?就在我创建 ListView 之前的 WM_CREATE 中?我已经输入了代码,但它没有进入 if 语句,并且没有真正发生任何事情......它没有进入 ProcessCustomDraw 函数......我注意到在 if(((LPNMHDR)lParam)-&gt;code == NM_CUSTOMDRAW) 中,变量((LPNMHDR)lParam)-&gt;code 永远不会等于NM_CUSTOMEDRAW...我需要使用SendMessage(Hwnd, NM_CUSTOMEDRAW, ....) 之类的东西吗?
    • 我对你的代码有点困惑,不知道如何使用它...如果你能解释更多如何使用它真的很有帮助...谢谢!
    • 我添加了一个小例子来说明我是如何做到的。使用的方法 codeproject 对我来说不太适用,所以我将绘图嵌入到主事件循环中(出于审美原因,您可能希望将其移动到其他地方;))
    猜你喜欢
    • 1970-01-01
    • 2013-02-12
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 2016-03-13
    • 2017-07-03
    相关资源
    最近更新 更多