Para mantener esta publicación lo más breve posible, permítanme decir que necesito mover todos los elementos seleccionados en la vista de lista debajo de cierto elemento (no seleccionado).
Navegando a través de la documentación de la vista de lista, encontré el mensaje LVM_SORTITEMSEX .
Cómo usar el mensaje anterior para lograr mi objetivo.
Hasta ahora, al usar este mensaje, pude mover todos los elementos seleccionados al final de la lista -> la vista de lista está ordenada de tal manera que los elementos no seleccionados preceden a los seleccionados.
Simplemente no puedo entender cómo implementar el movimiento de los elementos seleccionados debajo de cierto elemento.
A continuación se muestran las imágenes de lo que obtengo y lo que quiero lograr:

La imagen de la izquierda muestra lo que obtengo cuando uso el código enviado a continuación, mientras que la de la derecha muestra el resultado que busco.
Aquí están los fragmentos de código relevantes:
// compare function -> see the documentation int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM hwnd) { LVITEM lvi1 = { 0 }, lvi2 = { 0 }; // get selected state of the first item lvi1.iItem = (int)lParam1; lvi1.iSubItem = 0; lvi1.mask = LVIF_STATE; lvi1.stateMask = LVIS_SELECTED; ListView_GetItem((HWND)hwnd, &lvi1); // get selected state of the second item lvi2.iItem = (int)lParam2; lvi2.iSubItem = 0; lvi2.mask = LVIF_STATE; lvi2.stateMask = LVIS_SELECTED; ListView_GetItem((HWND)hwnd, &lvi2); // if first is selected and second is not selected, swap them if ((lvi1.state & LVIS_SELECTED) && (0 == (lvi2.state & LVIS_SELECTED))) return 1; return 0; } // somewhere in code, on button click for example ListView_SortItemsEx(hwndListView, CompareFunc, hwndListView); Pasé el identificador de vista de lista como tercer parámetro a ListView_SortItemsEx para poder usar ListView_GetItem en CompareFunc .
Si entiendo esto correctamente, desea reorganizar los elementos con arrastrar y soltar, y desea que la función de clasificación lo haga. Esto podría complicarse si se hace dentro del proceso de ordenación. Otra solución es encontrar el arreglo primero.
LVITEM::lParamListView_SortItems (no a ListView_SortItemsEx ) El único problema es que tal vez lParam se usó por otras razones. Tenemos que guardar lParam y luego restaurarlo después de realizar la clasificación.
También es mejor si ListView tiene LVS_SHOWSELALWAYS .
Tenga en cuenta que este método mueve elementos antes de la "marca roja". En su ejemplo, debe configurar redMark = 3 para mover la selección antes del "Artículo 60"
int CALLBACK CompareFunc(LPARAM lp1, LPARAM lp2, LPARAM) { return lp1 > lp2; } void sort() { int redMark = 3; int count = ListView_GetItemCount(hwndListView); std::vector<int> order; std::vector<LPARAM> saveLParam(count); //add everything before redMark for (int i = 0; i < redMark; i++) order.push_back(i); //add highlighted items for (int i = redMark; i < count; i++) if (ListView_GetItemState(hwndListView, i, LVIS_SELECTED)) order.push_back(i); //add the rest for (int i = redMark; i < count; i++) if (!ListView_GetItemState(hwndListView, i, LVIS_SELECTED)) order.push_back(i); if (order.size() != count) { assert(0); return; } //set lParam for (int i = 0; i < count; i++) { LVITEM item = { 0 }; item.iItem = order[i]; item.mask = LVIF_PARAM; //save old LParam value ListView_GetItem(hwndListView, &item); saveLParam[i] = item.lParam; //set new lParam item.lParam = i; ListView_SetItem(hwndListView, &item); } ListView_SortItems(hwndListView, CompareFunc, 0); //restore old lParam for (int i = 0; i < count; i++) { LVITEM item = { 0 }; item.iItem = order[i]; item.mask = LVIF_PARAM; item.lParam = saveLParam[order[i]]; ListView_SetItem(hwndListView, &item); } ::SetFocus(hwndListView); }Introducción:
LVM_SORTITEMSEX , todos los artículos deben tener lParam únicoslParam cuidadosamente diseñados tampoco son suficientes para conocer el orden original de los elementos.lParam en lugar de preparar el orden deseado de los elementos por separado, pero esto es bastante sucio y propenso a errores.Solución genérica
lParam únicosLVM_SORTITEMSEX , prepare un vector de lParam en el orden deseado:lParam en el vector.lParam en el vector.lParam en el vector.lParam : inicio de la lista, luego los elementos seleccionados conservan su orden original, luego los elementos no seleccionados conservan su orden original.lParam en el vector y responda en función de estas posiciones. Por ejemplo, si encuentra que la primera posición es menor que la segunda, devuelve un número negativo. El enfoque típico es return (firstPos - secondPos) , que manejará todas las órdenes relativas de firstPos y secondPos en una línea de código.