我在 Windows 上的 MSVC 2012 下使用 C++。我使用的是带对话框的纯 Win32,没有 MFC。
我有给定项目的 LVITEM 结构。我想更改给定 ListView 上项目的索引,以便我可以重新排序项目的位置。该.iItem
属性本质上是我要更改的内容,但是,我不知道如何使更改反映在列表视图中。
如果可能的话,我希望 ListView 自动将项目移动到我移动项目的下方,而不是覆盖新位置中的现有项目。
列表视图项的索引只会作为操作项集合的副作用而改变。您可以通过在它之前插入一个新项目 LVM_INSERTITEM 来增加它。您可以通过删除它之前的一个项目 LVM_DELETEITEM 来减少它。您可以通过先删除项目来移动项目,然后将其重新插入到另一个位置。或者通过交换 LVITEM 属性。
必须处理子项使这有点尴尬,但这就是编写本机 win32 代码的麻烦。这就是为什么有这么多类库可以使这更容易的原因。受到推崇的。
有一种方法可以移动列表视图的项目而不删除/重新创建它们:排序
如果你想在其他参考项目之前移动一个项目,这个代码必须做到这一点:
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;
}
这是一个片段:)
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);