LVM_GETNEXTITEM在listview中找不到项 我在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 ); 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; } }

LVM_GETNEXTITEM在listview中找不到项 我在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 ); 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; } },c++,listview,winapi,C++,Listview,Winapi,并按以下方式插入项目: int行=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++; } 之后,我想处理用户在此l

并按以下方式插入项目: int行=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++;
} 
之后,我想处理用户在此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 );
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;
        }
    }
不幸的是,当我点击这个listview时,我在listview中没有得到任何项目,并且我不能选择任何项目。我想强调的是,listview中有正确的项目,我可以滚动它,但当我点击它时,它没有标记。 提前感谢您的帮助

问题是在listview处理单击之前发送NM_单击。在收到通知时,该项目实际上尚未被选中

要查找的正确通知是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;
问题是在listview处理单击之前发送NM_单击。在收到通知时,该项目实际上尚未被选中

要查找的正确通知是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;

@RichardCriten我应该在哪里使用它?@RichardCriten这是ListVIew的正确解决方案还是仅适用于ListBox?LBN_SELCHANGE是ListBox控件WM_命令通知。这不是列表视图通知。@JonathanPotter,谢谢。我需要listView的解决方案。@RichardCriten我应该在哪里使用它?@RichardCriten这是listView的正确解决方案还是仅适用于ListBox?LBN\u SELCHANGE是ListBox控件WM\u命令通知。这不是列表视图通知。@JonathanPotter,谢谢。我需要listView的解决方案。您不需要比较新旧状态。只要ifplv->uChanged&LVIS_SELECTED就足够了。@zett42你知道我为什么不能选择行吗?@BartoszMajkut你说我不能选择行是什么意思吗?@zett42我使用了乔纳森的代码,当我点击listview时,我不能标记任何东西。@BartoszMajkut显然,你所观察到的东西不能来自乔纳森的代码。这段代码只是观察,它不会改变列表视图控件中选择的工作方式。我相信这个问题源于我们没有看到的代码部分。要缩小问题范围,请删除代码片段,直到问题不再发生。然后添加回代码,直到再次发生。你现在可以知道问题的原因了,你不需要比较新旧状态。只要ifplv->uChanged&LVIS_SELECTED就足够了。@zett42你知道我为什么不能选择行吗?@BartoszMajkut你说我不能选择行是什么意思吗?@zett42我使用了乔纳森的代码,当我点击listview时,我不能标记任何东西。@BartoszMajkut显然,你所观察到的东西不能来自乔纳森的代码。这段代码只是观察,它不会改变列表视图控件中选择的工作方式。我相信这个问题源于我们没有看到的代码部分。要缩小问题范围,请删除代码片段,直到问题不再发生。然后添加回代码,直到再次发生。您现在可能知道问题的原因。