【问题标题】:Win32 change list view item indexWin32 更改列表视图项索引
【发布时间】:2013-03-16 09:46:37
【问题描述】:

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

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

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

【问题讨论】:

  • 您是在谈论 ListView 何时处于报告(详细信息)模式,还是其中一种图标视图?
  • 报告/详细视图:)
  • 我认为不可能通过更改它们的索引来移动它们。没有LVM_SETITEMINFO 消息或类似的东西。 (好吧,有LVM_SETITEM,但这不能更改索引,因为它使用它来识别项目。)我见过的唯一方法是从当前位置删除项目,然后重新插入它进入新的位置。希望其他人知道我不知道的事情!
  • 唉,据我所知,这会破坏子项,我需要保留子项:(

标签: c++ winapi


【解决方案1】:

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

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

【讨论】:

  • 他说了什么。尽管您可以使用另一种方法来对列表进行排序,LVM_SORTITEMS 和一个聪明的比较过程可以按照您想要的方式对它们进行排序。
  • LVM_SORTITEMS 是永久的吗?即:如果我改变排序,它是累积的吗?
【解决方案2】:

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

如果你想在其他参考项目之前移动一个项目,这个代码必须做到这一点:

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

【讨论】:

    【解决方案3】:

    这里是sn-p :)

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

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 2016-10-07
      • 2016-03-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多