Win32更改列表视图项索引

时间:2013-03-16 09:46:37

标签: c++ winapi

我在Windows上的MSVC 2012下使用C ++。我使用纯Win32 w /对话框,没有MFC。

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

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

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

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

如果要在其他参考项目之前移动项目,则此代码必须有效:

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

答案 2 :(得分:0)

以下是代码段:)

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