[ListView] Alle Items "nicht" markieren?
-
Hau rein,
hast Du eine Lösung parrat?Gruß
-
ChrisK schrieb:
hast Du eine Lösung parrat?
So vielleicht?
HWND hWndLV = GetDlgItem(hWnd, ID_LISTVIEW); INT_PTR nIndex; while(-1 != (nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_ALL | LVNI_SELECTED))) ListView_SetItemState(hWndLV, nIndex, 0, LVIS_SELECTED);
-
-King- schrieb:
ChrisK schrieb:
hast Du eine Lösung parrat?
So vielleicht?
HWND hWndLV = GetDlgItem(hWnd, ID_LISTVIEW); INT_PTR nIndex; while(-1 != (nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_ALL | LVNI_SELECTED))) ListView_SetItemState(hWndLV, nIndex, 0, LVIS_SELECTED);
Sauber! Das funktioniert.
Eine neue Frage noch: wisst ihr, wie ich ein Item "verschieben" kann? Folgendes problem:
ich habe nichts gefunden, also keine Funktion, mit welcher man direkt ein Item verschieben kann. Darum habe ich das Item gelöscht, welches man verschieben will, und an der bestimmten Stelle wieder eingefügt. Jetzt gibt's da ein Problem. Ich habe eine Sortierungsfunktion geschrieben, mit der ich die Liste bi einem Columnklick sortieren kann. Bei InsertItem gebe ich also in der LVITEM Struct dem lParam Parameter die Position des gerade eingefügten Items (so funktioniert die Sortierungsfunktion). Wenn ich nun aber ein Item verschiebe (alte Position löschen, bei neuer einfügen) dann geht das Sortieren nicht mehr richtig.
Was ich erreichen will, ist: ich möchte 3 Items von unterschiedlicher Position an den ANFANG der liste verschieben. So dass die 3 Items OBEN sind. Was wäre da die beste Lösung, damit nachher das Sortieren weiterhin funktioniert?Danke im Voraus, Chris.
-
Wie wär's, wenn du für das Sortieren ListView_SortItems() benutzt?
-
Jau da hast Du mich eventuell falsch verstanden... Also mit SortItems arbeite ich bereits! Aber was ich nun machen will, ist, 3 Items, sagen wir Item 5, 7 und 10 nach oben (an den Anfang der Liste) zu verschieben!
-
Löschen und an der richtigen Stelle wieder einfügen.
-
narf! <-- woher kommt denn das wort? weiß es echt nicht, sagts mal kurz :>
narf, hatte ich doch oben geschrieben. ließt du die letzten beiträge auch? habe ich ja so gemacht... und dann funktioniert das SORTIEREN eben nicht mehr (ich denke, weil die nach oben eingefügten items alle logischerweise die NVITEM->iItem = 0 bekommen)! hatte das auch probiert, dass ich den wert beim verschieben NICHT = 0 setze... geht trotzdem nicht. woran könnts liegen, dass das sortieren dann nicht mehr funktioniert?
soll ich nach dem verschieben etwa jedes item einzeln nochmal durchrattern, und jedem eine neue iItem zuweisen? das oberste 0, das 2. 1 und so?
Thanks, chris
-
Könntest du bitte näher beschreiben, was du mit "dann geht das Sortieren nicht mehr richtig" meinst? Ein wenig Code wäre auch zweckmäßig, so z.B. die Sortier Callback-Prozedur.
-
Najuuuuut! ^^
Also passt auf. Ich habe eine Liste (ReportView). 11 Spalten.
Meine Sortierfunktion:// ... #define NO_OF_SUBITEM 3 typedef struct _tagSORTDATA{ HWND hwndList; int isortSubItem; int iUPDOWN; } SORTDATA; #define UP 1 #define DOWN 2 // ... int CALLBACK ListViewCompareFunc(LPARAM lp1, LPARAM lp2, LPARAM lp3) { static LVFINDINFO lvf; static int nItem1, nItem2; static char buf1[MAX_PATH], buf2[MAX_PATH]; SORTDATA *lpsd; lpsd = (SORTDATA *)lp3; lvf.flags = LVFI_PARAM; lvf.lParam = lp1; nItem1 = ListView_FindItem(lpsd->hwndList, -1, &lvf); lvf.lParam = lp2; nItem2 = ListView_FindItem(lpsd->hwndList, -1, &lvf); ListView_GetItemText(lpsd->hwndList, nItem1, lpsd->isortSubItem, buf1, sizeof(buf1)); ListView_GetItemText(lpsd->hwndList, nItem2, lpsd->isortSubItem, buf2, sizeof(buf2)); if(lpsd->iUPDOWN == UP) return(stricmp(buf1, buf2)); else return(stricmp(buf1, buf2) * -1); } // ... Bei Columnklick folgendes: NMLISTVIEW *lpnmlistview; lpnmlistview = (LPNMLISTVIEW)lParam; if(lpnmlistview->hdr.code == LVN_COLUMNCLICK) { isortsubno = lpnmlistview->iSubItem; if(sortsubno[isortsubno] == UP) sortsubno[isortsubno] = DOWN; else sortsubno[isortsubno] = UP; SortData.hwndList = GetDlgItem(hMainWnd, IDC_LIST1); SortData.isortSubItem = isortsubno; SortData.iUPDOWN = sortsubno[isortsubno]; if(ListView_SortItems(GetDlgItem(hMainWnd, IDC_LIST1), ListViewCompareFunc, &SortData) != TRUE) MessageBox(hMainWnd, "??? ListView", "Error", MB_OK); } // ... Item einfügen (wenn man meiner Einfüg-Fuktion -1 übergibt, dann soll das Item am Ende eingefügt werden. Andernfalls an der angegebenen Position). ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT | LVIF_PARAM; if(iPos == -1) lvi.iItem = ListView_GetItemCount(hListViewCtrl); else lvi.iItem = iPos; lvi.pszText = szColumn0; lvi.lParam = lvi.iItem; lvi.cchTextMax = lstrlen(lvi.pszText); ListView_InsertItem(hListViewCtrl, &lvi);
Sodele. Das Sortieren geht wunderbar!!! Alles roger. So. Nun muss ich verschiedene Items (genauergesagt, die Items, die meine Suchfunktion findet) nach oben schieben. An den Anfang der Liste.
Hier folgt nun der Code, wo ich einen String in jedem Item suche! Wenn ein Item gefunden wird, so soll es an den Anfang verschoben werden und markiert werden! So findet man seine Items die man sucht:
for(int i=0; i<ListView_GetItemCount(GetDlgItem(hMainWnd, IDC_LIST1)); i++) { ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, iSearchColumn, szItemText, MAX_PATH); CharLowerBuff(szItemText, MAX_PATH); CharLowerBuff(szSearchString, MAX_PATH); if(strstr(szItemText, szSearchString) != NULL) { char szText1[MAX_PATH]; char szText2[MAX_PATH]; char szText3[MAX_PATH]; char szText4[MAX_PATH]; char szText5[MAX_PATH]; char szText6[MAX_PATH]; char szText7[MAX_PATH]; char szText8[MAX_PATH]; char szText9[MAX_PATH]; char szText10[MAX_PATH]; char szText11[MAX_PATH]; ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 0, szText1, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 1, szText2, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 2, szText3, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 3, szText4, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 4, szText5, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 5, szText6, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 6, szText7, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 7, szText8, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 8, szText9, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 9, szText10, MAX_PATH); ListView_GetItemText(GetDlgItem(hMainWnd, IDC_LIST1), i, 10, szText11, MAX_PATH); ListView_DeleteItem(GetDlgItem(hMainWnd, IDC_LIST1), i); ListView_InsertItemEx(GetDlgItem(hMainWnd, IDC_LIST1), szText1, szText2, szText3, szText4, szText5, szText6, szText7, szText8, szText9, szText10, szText11, 0, true); ListView_SetItemState(GetDlgItem(hMainWnd, IDC_LIST1), 0, LVIS_SELECTED, LVIS_SELECTED); iMatches++; } else ListView_SetItemState(GetDlgItem(hMainWnd, IDC_LIST1), i, 0, LVIS_SELECTED); } sprintf(szMsg, "Die Suche nach '%s' ist beendet. %i Einträge gefunden.", szSearchString, iMatches); StatusText(szMsg, NULL, NULL, NULL, NULL); SetFocus(GetDlgItem(hMainWnd, IDC_LIST1));
Jau! Das Problem nun ist ganz einfach! Nach dem ein Item von meinem Programm nach oben (Position 0) berschoben wurde, kann ich die Liste nicht mehr (so richtig) sortieren! Es sortiert glaube ich nur alle, die nicht verschoben wurden. Die Verschoebenen spielen verrückt.
-
-King-, WebFritzi und Shlo, bitte stellt Euch nicht so an. Ihr wisst bestimmt, was ich falsch mache?
-
Sollen die nach oben geschobenen Einträge eigentlich dort verbleiben, oder wieder einsortiert werden?
Ich denke aber, dass es daran liegt:Note
During the sorting process, the list-view contents are unstable. If the callback function sends any messages to the list-view control, the results are unpredictable.Versuchs mal statt ListView_SortItems mit ListView_SortItemsEx:
You can send an LVM_GETITEMTEXT message to retrieve further information on an item, if needed.
[...]
With ListView_SortItemsEx, the item's index is passed instead of its lparam value.Note
During the sorting process, the list-view contents are unstable. If the callback function sends any messages to the list-view control aside from LVM_GETITEM (ListView_GetItem), the results are unpredictable.
-
Was steht denn in dem lParam's der LV_ITEM's? Da solltest du doch deine Informationen über jedes einzelne Item reinschreiben. Dann brauchst du in der Sortierfunktion auch nicht ListView_GetItemText() und ListView_FindItem() zu verwenden. Daran liegt es ganz sicher.
-
ChrisK schrieb:
narf! <-- woher kommt denn das wort? weiß es echt nicht, sagts mal kurz :>
Kommt meines Wissen von "Pinky und Brain"
-
:>
Ich probiers mal mit felnders Antwort hinzubekommen.Gruß!
-
Damit wirst du leider keinen Erfolg haben. Aber wenn du ein Prog haben willst, das nicht funktioniert, ist dir auch nicht mehr zu helfen...
-
Wieso sagst Du sowas und schreibst keine Lösung? Wieso sagst Du, "wenn ich ein Prog haben will, das nicht funktioniert,...". Is doch SCHEISSE?
:>Hört sich an als wüsstest Du, was ich tun solle, dann wär's kewl gewesen, wenn Du das gleich geschrieben hättest. Ich wäre dann zufrieden, und ich könnte mir die Nachfrage sparen und Du ein extra Posting, wär doch besser oder? :>
Also rück raus bitte *g
-
ChrisK schrieb:
Hört sich an als wüsstest Du, was ich tun solle, dann wär's kewl gewesen, wenn Du das gleich geschrieben hättest.
Du bist echt ein Blödmann. Wozu schreibe ich eigentlich Beiträge, wenn du sie nicht liest. Ich hab dir bereits gesagt, was du tun sollst! Du sollst für jede Zeile einen Datensatz bereit halten und diesen im LV_ITEM::lParam speichern. Bei LVN_GETDISPINFO sollst du dann für jedes Item den Text anzeigen, den du eben aus dem lParam von TV_ITEM holst. In der Sortierfunktion bekommst du diese lParams in den Parametern mitgeschickt und kannst direkt auf den Text zugreifen ohne ListView_GetItemText() zu verwenden. Ich wiederhole mich ungern!
-
Und warum sollte meine Variante nicht funktionieren
-
Du bist echt ein Blödmann.
Ehm, das ist sehr... Ihr wisst schon. Das Thema ist für mich geschlossen, danke WebFritzi.
Thx @ flenders ich lese mal die Stellen die Du da gefunden hast nochmal nach!
-
Okay, ich weiß zwar nicht @flenders, ob das die eleganteste Lösung war, aber schau Dir mal diesen Code an:
for(int i=0; i<ListView_GetItemCount(GetDlgItem(hMainWnd, IDC_LIST1)); i++) { LVITEM lvi; lvi.iItem = i; ListView_GetItem(GetDlgItem(hMainWnd, IDC_LIST1), &lvi); lvi.lParam = i; ListView_SetItem(GetDlgItem(hMainWnd, IDC_LIST1), &lvi); }
Das rufe ich nach dem "Verschieben" der Items auf! Was passiert? Jedes Item bekomm ein frisches, geordnetes lParam. Ergebnis? Die Liste lässt sich nach dem "Verschieben" 1A sortieren!