Win32更改列表视图项索引 我在Windows下使用MSVC 2012的C++。我使用的是纯Win32 w/对话框,没有MFC

Win32更改列表视图项索引 我在Windows下使用MSVC 2012的C++。我使用的是纯Win32 w/对话框,没有MFC,c++,winapi,C++,Winapi,我有一个给定项的LVITEM结构。我想更改给定ListView上项目的索引,以便可以重新排列项目的位置。.iItem属性本质上就是我要更改的,但是,我不知道如何在列表视图中反映更改 如果可能的话,我希望ListView自动将项目移动到我移动项目的位置下方,而不是覆盖新位置中的现有项目。列表视图项目的索引将仅作为操作项目集合的副作用而更改。您可以通过在它之前插入一个新项LVM_INSERTITEM来增加它。您可以通过删除其前面的项目LVM_DELETEITEM来减少它。通过先删除项目,然后将其重新

我有一个给定项的LVITEM结构。我想更改给定ListView上项目的索引,以便可以重新排列项目的位置。
.iItem
属性本质上就是我要更改的,但是,我不知道如何在列表视图中反映更改


如果可能的话,我希望ListView自动将项目移动到我移动项目的位置下方,而不是覆盖新位置中的现有项目。

列表视图项目的索引将仅作为操作项目集合的副作用而更改。您可以通过在它之前插入一个新项LVM_INSERTITEM来增加它。您可以通过删除其前面的项目LVM_DELETEITEM来减少它。通过先删除项目,然后将其重新插入另一个位置来移动项目。或者通过交换LVITEM属性


必须处理子项使得这有点尴尬,但这就是编写本机win32代码的麻烦。这就是为什么有如此多的类库可以让这变得更容易。推荐使用。

有一种方法可以移动listview的项目而不删除/重新创建它们:排序

如果要在其他引用项之前移动项,则此代码必须执行以下操作:

struct info {
   int item_to_move_before_reference;
   int item_reference;
};

int CALLBACK CompareFunc(LPARAM item1, LPARAM item2, info* i) {

   if(item1 == i->item_to_move_before_reference) {
      item1 = i->item_reference;
   } else if(item1 >= i->item_reference) {
      item1++;
   }

   if(item2 == i->item_to_move_before_reference) {
      item2 = i->item_reference;
   } else if(item2 >= i->item_reference) {
      item2++;
   }

   return item1 - item2;
}

bool sort_items(HWND listview, int item_to_move_before_reference, int item_reference) {
   if(item_to_move_before_reference < item_reference) return false;
   info i;
   i.item_to_move_before_reference = item_to_move_before_reference;
   i.item_reference = item_reference;
   ListView_SortItemsEx(listview, CompareFunc, &i);
   return true;
}
结构信息{ int item_to_move_在_引用之前; int项目_参考; }; int回调CompareFunc(LPARAM item1、LPARAM item2、info*i){ if(item1==i->item_to_move_before_reference){ item1=i->item\u参考; }否则如果(项目1>=i->项目\参考){ 项目1++; } if(item2==i->item_to_move_before_reference){ item2=i->item\u参考; }否则如果(项目2>=i->项目\参考){ 项目2++; } 返回项目1-项目2; } bool排序项目(HWND列表视图、int-item\u-to\u-move\u-before\u-reference、int-item\u-reference){ if(item_to_move_before_reference这里有一个片段:)

bool isUp=。。。;
HWND hListWnd=。。。;
int pos=ListView_GetNextItem(hListWnd,-1,选择LVNI_);
如果(pos=-1 | | pos==0&&isUp | | pos==ListView_GetItemCount(hListWnd)-1&&isUp)
返回true;
pos=是up吗?pos-1:pos;
HWND hHeader=ListView\u GetHeader(hListWnd);
对于(int i=0;i
您是在谈论ListView何时处于报告(详细信息)模式,还是图标视图之一?报告/详细信息视图:)我认为不可能通过更改其索引来移动项目。没有
LVM_SETITEMINFO
消息或类似的消息。(当然,有
LVM_SETITEM
,但这无法更改索引,因为它使用它来标识项目。)我所见过的唯一方法是从当前位置删除项目,然后将其重新插入新位置。希望有人知道一些我不知道的事情!唉,据我所知,这会破坏子项,我需要保留子项:(他说的。尽管你可以用
LVM_SORTITEMS
对列表进行排序,并用一个聪明的比较程序按你想要的方式排序。LVM_SORTITEMS是永久的吗?即:如果我更改排序,它是累积的吗?
bool isUp = ...;
HWND hListWnd = ...;
int pos = ListView_GetNextItem(hListWnd, -1, LVNI_SELECTED);
if (pos == -1 || pos == 0 && isUp || pos == ListView_GetItemCount(hListWnd) - 1 && !isUp)
    return true;

pos = isUp ? pos - 1 : pos;

HWND hHeader = ListView_GetHeader(hListWnd);
for (int i = 0; i < Header_GetItemCount(hHeader); i++) {
    TCHAR buf[255]{0};
    ListView_GetItemText(hListWnd, pos, i, buf, 255);
    LVITEM lvi = {0};
    lvi.mask = LVIF_TEXT;
    lvi.iItem = pos + 2;
    lvi.iSubItem = i;
    lvi.pszText = buf;
    lvi.cchTextMax = 255;
    if (i == 0)
        ListView_InsertItem(hListWnd, &lvi);
    else
        ListView_SetItem(hListWnd, &lvi);
}

ListView_DeleteItem(hListWnd, pos);

if (!isUp)
    ListView_SetItemState (hListWnd, pos + 1, LVIS_FOCUSED | LVIS_SELECTED, 0x000F);