CListCtrl markierte Zeilen löschen
-
Hallo,
ich lösche mit Entf markierte Zeilen aus einer ListCtrl. Wenn ich eine Zeile markiert habe klappt das auch wunderbar. Nur bei der Selektion mehrerer Zeilen werden nicht alle gelöscht. Je mehr markiert, je mehr bleiben übrig - aber ohne allgemeines Prinzip.
void CDMView::OnLvnKeydownHistorie(NMHDR *pNMHDR, LRESULT *pResult) { TRACE0("Keypress in Historie"); LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR); // wenn Entf gedrück wurde markierte Elemente löschen if (pLVKeyDow->wVKey == VK_DELETE) { TRACE0("Keypress in Historie: ENTF"); // Zeiger auf Historie (CListCtrl) holen CListCtrl* pList = (CListCtrl*) GetDlgItem(IDC_HISTORIE); // erstes selektiertes Element POSITION pos = pList->GetFirstSelectedItemPosition(); // solange noch selektierte Elemente while (pos) { // nächstes Element int nItem = pList->GetNextSelectedItem(pos); TRACE1("Item %d was selected!\n", nItem); // ermittle die Nummer für die Historie (Datenklasse) int nItemH = atoi(pList->GetItemText(nItem, 0)); // Lösche markiertes Zeile (CListCtrl) pList->DeleteItem(nItem); // lösche das Element aus der Historie (Datenklasse) GetDocument()->GetHistorie()->DeleteValue(nItemH); } } *pResult = 0; }Wer kann mir helfen?
Gruß
Chris
-
So lösche ich die selektierten Items aus einer Liste
if(AfxMessageBox("Die gewählten Einträge löschen?",MB_YESNO)==IDYES) { CListCtrl l; CListCtrl * a; LVITEM lv; lv.mask =LVIF_STATE; lv.stateMask = LVIS_SELECTED; a = (CListCtrl *) l.FromHandle(active); while(a->GetSelectedCount() > 0) { for(int x = 0;x <=a->GetItemCount();x++) { lv.iItem = x; a->GetItem(&lv); if(lv.state == LVIS_SELECTED) { a->DeleteItem(x); } } } }
-
@Andorxor
Oje, ne ineinandergeschachtelte Schleife für ein simples lineares Problem?@MuehBln
Schon nicht schlecht, allerdings hast Du vergessen, dass du das Item an Position N löschst und danach aufgrund von GetNextSelectedItem mit N+2 weiteriterierst. Also wird Item N+1 einfach im Text übergangen.Also folgt:
// solange noch selektierte Elemente for( int nItem=0; nItem=pList->GetNextItem( nItem, LVNI_SELECTED)!=-1; ) { // nächstes Element TRACE1("Item %d was selected!\n", nItem); // ermittle die Nummer für die Historie (Datenklasse) int nItemH = atoi(pList->GetItemText(nItem, 0)); // Lösche markiertes Zeile (CListCtrl) pList->DeleteItem( nItem); // lösche das Element aus der Historie (Datenklasse) GetDocument()->GetHistorie()->DeleteValue(nItemH); }
-
Dankeschön!
-
leider klappt Deine Funktion nicht. Egal was ich markiere, werden jetzt alle Elemente bis auf das 1 und das letzte gelöscht. Das letzte kann ich danach noch separat markieren und löschen. Aber das Oberste geht gar nicht zu löschen.
Kannst Du mir nochmal helfen?
Gruß
Chris
-
'tschuldigung, hab die Klammern vergessen, so isses richtig:
for( int nItem=0; (nItem=pList->GetNextItem( nItem, LVNI_SELECTED))!=-1; )
-
klappt leider immer noch nicht. Bin schon mit dem Debugger durch seh den Fehler aber nicht.

Also das sieht ja vollkommen logisch und elegant aus - aber er löscht nicht alle gewählten Elemente. Wähle ich einzelne Zeilen die nicht direkt übereinander liegen oder eine einzelne Zeile wähle klappts.
Aber wenn ich einen ganzen Block wähle, löscht er nicht alle.
-
Bei mir gehts!
Ähm, hast Du vielleicht LVS_ICON oder LVS_SMALLICON eingestellt?
-
Nein, hab bei Ansicht Bericht zu stehen.
Ich füge die Elemente mit:
int pos = m_Historie.InsertItem(LVIF_TEXT|LVIF_STATE, val->GetID(), val->GetIDString(), 0, LVIS_SELECTED, 0, 0);liegts am LVIS_SELECTED?
-
Ich hab MFC7, da gibts die Funktion mit so vielen Parametern gar net! Was bedeuten die?
-
Hi René,
ich benutze auch MFC7 (also, wenn Du damit VS.NET meinst)
und diese Funktion habe ich aus der MSDN....InsertItem(UINT nMask, int nItem, LPCSTR lpszItem, UINT nState, UINT nStateMask, nImage, LPARAM lParam)Sollte ich eine Alternative zum Einfügen neuer Elemente benutzen?
-
Da Du beim State des Items 0 angibst, heisst es, dass das Item unselektiert eingefügt wird, damit kannst Du dann gleich die Funktion
int InsertItem( int nItem, LPCTSTR lpszItem);
benutzen.Allerdings frage ich mich, was Deine Funktion 'val->GetID()' macht.
Wenn z.B. GetID Deines 1. Items 10 zurückgibt, wohin soll dann InsertItem das Item einfügen, wenn es Index 0..9 noch gar nicht gibt?
-
ich benötige eine laufende Nummer für die Values (val->GetID()). Da beim Löschen von Elementen trotzdem weiter hochgezählt werden muss, kann ich also den CArray-Index nicht benutzen. Deshalb diese ID.
Dein geschilderter Fall mit den Indexen tritt ganz sicher in der Konstellation auf.
Spielt der Wert des nItem überhaupt eine Rolle? InsertItem fügt doch den Wert eh sortiert an einer ganz anderen Stelle ein und gibt mir eine ganz andere Einfügeposition zurück.
Oder versteh ich da prinzipiell was falsch?
-
Du brauchst ihn wenn du die Liste sortieren willst.
-
Ups

Es ist natürlich so, dass GetNextItem schon aufgrund des Namens das aktuell übergebene Item gar nicht mehr überprüft.
Demzufolge also so:for( int nItem=-1; (nItem=pList->GetNextItem( nItem, LVNI_SELECTED))!=-1; nItem--)Man man man, die Hitze macht mir wirklich zu schaffen

-
Hier ist's gar nicht so warm...

Wunderbar!!! Klappt jetzt supi!!!

Dankeschön für Deine Geduld!Gruß
Chris