Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

130
Views
Mueva todos los elementos seleccionados debajo de uno específico con LVM_SORTITEMSEX

INTRODUCCIÓN:

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 .

PREGUNTA:

Cómo usar el mensaje anterior para lograr mi objetivo.

MIS ESFUERZOS PARA SOLUCIONAR ESTO:

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:

ingrese la descripción de la imagen aquí

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 .

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

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.

  • Use vector para almacenar elementos antes de "redMark"
  • Agregar elementos seleccionados que aparecen después de "redMark"
  • Agregar elementos no seleccionados que aparecen después de "redMark"
  • Guarde este pedido en LVITEM::lParam
  • Llame a ListView_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); }
over 4 years ago · Santiago Trujillo Report

0

Introducción:

  • Para LVM_SORTITEMSEX , todos los artículos deben tener lParam únicos
  • Para pasar varios parámetros a la devolución de llamada de clasificación, cree una estructura y pásele un puntero.
  • Tan pronto como comience a clasificar, el orden original de los elementos se pierde y ya no puede consultarlo si no está guardado en algún lugar.
  • Si puede repetir la operación de mover elementos ordenados, los lParam cuidadosamente diseñados tampoco son suficientes para conocer el orden original de los elementos.
  • Puede jugar con 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

  • Asegúrese de que todos los elementos tengan lParam únicos
  • Antes de llamar a LVM_SORTITEMSEX , prepare un vector de lParam en el orden deseado:
    1. Enumere los elementos en la lista desde el principio hasta el elemento de "marca roja", agregue sus lParam en el vector.
    2. Enumere los elementos en la lista desde el elemento de "marca roja" hasta el final de la lista, si el elemento está seleccionado, agregue su lParam en el vector.
    3. Enumere los elementos en la lista desde el elemento de "marca roja" hasta el final de la lista, si el elemento NO está seleccionado, agregue su lParam en el vector.
    4. Ahora tiene el orden de lParam : inicio de la lista, luego los elementos seleccionados conservan su orden original, luego los elementos no seleccionados conservan su orden original.
  • Pase ese vector para clasificar la devolución de llamada
  • En él, busque las posiciones de dos 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.
  • Eso hará que su devolución de llamada de clasificación aplique el orden preparado de elementos a la lista.
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!