虚拟列表视图无法获取CDDS_ITEMPREPAINT C ++ [英] Virtual listview doesn't get CDDS_ITEMPREPAINT c++

查看:440
本文介绍了虚拟列表视图无法获取CDDS_ITEMPREPAINT C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据我在文本框中键入的内容来更改listview项的颜色.当用户基于某种逻辑输入一些文本时,我有以下代码 ListView_SetItemState(hList,wordid,LVIS_FOCUSED | LVIS_SELECTED,LVIS_FOCUSED | LVIS_SELECTED);

I am trying to change the color of listview item based on what I type on text box. When user type some text based on some logic I use I have below code ListView_SetItemState(hList, wordid, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);

然后在我的WM_NOTIFY块上,我有了这个;

Then on my WM_NOTIFY block I have this;

case WM_NOTIFY:
{

    NMHDR *pNMHDR= (NMHDR*)lParam;

    switch(pNMHDR->code){
           case LVN_GETDISPINFO:
                OnGetdispinfo(pNMHDR);
                break;
            case NM_CUSTOMDRAW:
               wmnot= OnDraw(pNMHDR);
               return wmnot;
                break;
         }

    return 0;

}

OnGetdispinfo函数使用Sqlite填充我的虚拟列表视图.在我的ondraw函数中,我有这个

OnGetdispinfo function fills my virtual listview by using Sqlite. In my ondraw function I have this

int OnDraw (NMHDR* pNMHDR){
    int nIndex,state;
    int result;
    NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR ); 

if (pLVCD->nmcd.hdr.hwndFrom==hList)
{
    switch (pLVCD->nmcd.dwDrawStage)
    {
    case CDDS_PREPAINT:
        result= CDRF_NOTIFYITEMDRAW;
        break;
    case CDDS_ITEMPREPAINT:
        result=CDRF_NOTIFYSUBITEMDRAW;
        break;
    case CDDS_SUBITEM|CDDS_ITEMPREPAINT:
        nIndex=pLVCD->nmcd.dwItemSpec;
        state=ListView_GetItemState(hList,nIndex,LVIF_TEXT |LVIF_PARAM);
        if(state&LVIS_SELECTED==LVIS_SELECTED)   
        {
            pLVCD->clrTextBk=RGB(124,34,78);
            return CDRF_NEWFONT;
        }
        result= CDRF_DODEFAULT;
        break;
    default:
        result=CDRF_DODEFAULT;
        break;
    }
}
    return result;  // CDRF_DODEFAULT



}

我收到CDDS_PREPAINT消息,但根本没有收到CDDS_ITEMPREPAINT消息.

I get CDDS_PREPAINT message but I don't get CDDS_ITEMPREPAINT message at all.

我的Listview根据Spy ++具有这种样式

My Listview has this styles according to Spy++

WS_CHILDWINDOW WS_VISIBLE WS_VSCROLL WS_TABSTOP LVS_REPORT LVS_SINGLESEL LVS_SHOWSELALWAYS

WS_CHILDWINDOW WS_VISIBLE WS_VSCROLL WS_TABSTOP LVS_REPORT LVS_SINGLESEL LVS_SHOWSELALWAYS

WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR WS_EX_NOPARENTNOTIFY WS_EX_CLIENTEDGE

WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR WS_EX_NOPARENTNOTIFY WS_EX_CLIENTEDGE

推荐答案

我终于解决了这个问题.这是固定代码. 首先,我添加了onchange通知程序功能,以便可以检测到更改以进行选择.

I finally solved the problem. Here is the fixed code. First of all I added onchange notifier function so that I can detect changes for selection.

void OnItemChange (LPARAM lParam)
{

    LPNMLISTVIEW pNMListView = reinterpret_cast<LPNMLISTVIEW>(lParam);

    if ((pNMListView->uChanged & LVIF_STATE) 
        && (pNMListView->uNewState & LVNI_SELECTED))
    {

        ListView_RedrawItems(hList,Query.WordID,pNMListView->iItem);
        ListView_RedrawItems(hList,pNMListView->iItem,Query.WordID);
        Query.WordID=pNMListView->iItem;
        //DO STUFF;

    }


}

然后,我也修改了自定义绘图功能.

Then I modified my custom draw function as well.

LRESULT OnDraw  (LPARAM lParam)
{
    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
    int nIndex;
    int state;
    if (lplvcd->nmcd.hdr.hwndFrom!=hList)
        return CDRF_DODEFAULT;

    switch(lplvcd->nmcd.dwDrawStage) 
    {
    case CDDS_PREPAINT : //Before the paint cycle begins
        return  CDRF_NOTIFYITEMDRAW;
    case CDDS_ITEMPREPAINT: 
        return CDRF_NOTIFYSUBITEMDRAW;

    case CDDS_POSTPAINT:
        nIndex=lplvcd->nmcd.dwItemSpec;
        state=lplvcd->nmcd.uItemState;
        return CDRF_DODEFAULT;
    case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
        nIndex=lplvcd->nmcd.dwItemSpec;
        state=lplvcd->nmcd.uItemState;
        if  (  nIndex==Query.WordID)    {
        lplvcd->clrText   =  GetSysColor(COLOR_HIGHLIGHTTEXT);
        lplvcd->clrTextBk = GetSysColor(COLOR_HIGHLIGHT);
        return CDRF_NEWFONT;
        }
        else{

            lplvcd->clrText   = GetSysColor(COLOR_WINDOWTEXT);  
            lplvcd->clrTextBk = GetSysColor(COLOR_WINDOW); 
            return CDRF_NEWFONT;
        }
    default:
        return CDRF_DODEFAULT;

    }
    return CDRF_DODEFAULT;
}

所以基本上,我不是通过ListView Messages选择项目.相反,我将Query.WordID设置为我要选择的项目,并且如果选择了该项目(通过鼠标还是通过编程方式),我会手动更改该项目的颜色.

So basically, I am not selecting items by ListView Messages. Instead i set Query.WordID to the item I want to select and if the item is selected(either by mouse or programmatically) I manually change the color of the item.

这篇关于虚拟列表视图无法获取CDDS_ITEMPREPAINT C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆