LVM_GETNEXTITEM无法在listview中找到项目

时间:2018-01-18 17:00:44

标签: c++ listview winapi

我在c ++中遇到了listview的严重问题。 我创建了一个这样的:

RECT rcl;
GetClientRect( hWnd, & rcl );
lvC = CreateWindowEx( 0, WC_LISTVIEW, NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT |
LVS_EDITLABELS, 0, 0, rcl.right - rcl.left, 200 - rcl.top,
hWnd,( HMENU ) 1000, hInstance, NULL );

ListView_SetExtendedListViewStyle(lvChannels, LVS_EX_FULLROWSELECT);

LVCOLUMN lvc;
lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.iSubItem = 0;
lvc.cx = 750;
lvc.pszText = (char*)"Name";
ListView_InsertColumn( lvC, 0, & lvc );

以这种方式插入项目:     int row = 0;

for (const auto& c : cVec)
{
    LVITEM lvi;
    lvi.mask = LVIF_TEXT;

    lvi.pszText = (LPSTR)c.name.c_str();
    lvi.iItem = row;
    lvi.iSubItem = 0;

    ListView_InsertItem( lvC, & lvi );
    row++;
} 

之后我想在用户选择此列表视图中的行时进行处理。我尝试过这样的事情:

case WM_NOTIFY:
    {
        switch(LOWORD(wParam))
        {
            case 1000:
                if(((LPNMHDR)lParam)->code == NM_CLICK) 
                {
                    auto iSelect=SendMessage(lvC, LVM_GETNEXTITEM, -1, LVNI_SELECTED);

                    if(iSelect==-1)
                    {
                        MessageBox(hWnd,"No Items in ListView",
                        "Error",MB_OK|MB_ICONINFORMATION);
                        break;
                    }
                    else
                    {
                        std::string t = "Selected item: " + std::to_string(iSelect);
                        MessageBox(hWnd, t.c_str(),
                        "Error",MB_OK|MB_ICONINFORMATION);
                        break;
                    }
                }
            break;
        }
    }

不幸的是,当我点击这个列表视图时,我得到了#List; ListView中没有项目"而我无法选择任何一个。我想强调listview中有正确的项目,我可以滚动它但是当我点击它时,它没有标记。 提前感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

问题是在listview处理点击之前发送了NM_CLICK。当您收到通知时,该项目尚未实际选定。

要查找的正确通知是LVN_ITEMCHANGED,只要项目状态发生变化(包括其选择状态),就会发送该通知。

case WM_NOTIFY:
    if (reinterpret_cast<LPNMHDR>(lParam)->code == LVN_ITEMCHANGED)
    {
        auto plv = reinterpret_cast<NMLISTVIEW*>(lParam);
        if ((plv->uNewState & LVIS_SELECTED) != (plv->uOldState & LVIS_SELECTED))
        {
            // selection state of an item has changed
        }
    }
    break;