CTreeCtrl durchsuchen
-
Hi!
Ich würde gerne meine TreeCtrl nach einem bestimmten String durchsuchen, aber weis leider absolut nicht wie... Hab jetzt schon etliche Stunden damit verbracht aber hab all meine Idee und Gedanken leider nicht so umsetzten können das es klappt.Ich hoffe ihr könnt mir weiterhelfen...
Danke schonmal!!!
Chris
-
Sollte etwa so funktionieren:
- eine Membervariable zu dem TreeCtrl erstellen, über die man Zugriff auf die Memberfunktionen von CTreeCtrl erhält
- für die Suche eine extra Funktion erstellen
- den Rückgabewert der Memberfunktion GetRootItem() an die Suchfunktion übergeben
- in der Suchfunktion mit ItemHasChildren(...) überprüfen, ob Unterknoten vorhanden sind
- wenn ja, GetChildItem(...) aufrufen
- so lange der Rückgabewert von GetChildItem(...) nicht NULL ist, die Suchfunktion rekursiv aufrufen und mit GetNextSiblingItem(...) alle Unterknoten durchlaufenZwischendrin noch für jeden Eintrag GetItemText(...) aufrufen und mit dem Suchstring vergleichen.
-
Vielen Dank für deine Hilfe!
Ich hab das Ganze folgendermaßen gelöst:bool CPlanerTestDlg::SearchTree(CString szSearch) { HTREEITEM htrItem = NULL, htrItem2 = NULL, htrItem3 = NULL; BOOL hasCildren = false; htrItem = m_ctlTree.GetRootItem(); hasCildren = m_ctlTree.ItemHasChildren(htrItem); if(hasCildren == true) { htrItem2 = m_ctlTree.GetChildItem(htrItem); htrItem3 = m_ctlTree.GetChildItem(htrItem2); while(m_ctlTree.GetItemText(htrItem3) != szSearch && szSearch!="") { if(m_ctlTree.GetItemText(htrItem3) == "") { htrItem2 = m_ctlTree.GetNextSiblingItem(htrItem2); htrItem3 = m_ctlTree.GetChildItem(htrItem2); if(m_ctlTree.GetItemText(htrItem2) == "") { htrItem = m_ctlTree.GetNextSiblingItem(htrItem); htrItem2 = m_ctlTree.GetChildItem(htrItem); if(m_ctlTree.GetItemText(htrItem) == "") { break; } } } else { htrItem3 = m_ctlTree.GetNextSiblingItem(htrItem3); } } } if(m_ctlTree.GetItemText(htrItem3) == szSearch) { MessageBox("gefunden"); m_ctlTree.SelectItem(htrItem3); return true; } else { AfxMessageBox("Der angegebene Schüler hat kein Prüfungsfach gewählt oder ist nicht in der Datenbanke vorhanden!", MB_OK, MB_ICONEXCLAMATION); return false; } }
Für Verbesserungsvorschläge bin ich gerne offen!
Gruß
Chris
-
DarkAzReaL schrieb:
Für Verbesserungsvorschläge bin ich gerne offen!
OK, nur ein Vorschlag:
das rekursive hast du noch nicht drin.
Ich habe mir mal eine Funktion geschrieben, die einen kompletten Baum aufklappt.
Der Aufruf in OnInitDialog() sieht so aus:BaumAufklappen(m_Tree.GetRootItem());
Und die Funktion dazu sieht so aus:
void CBlaBlubb::BaumAufklappen(HTREEITEM TreeItem) { m_Tree.Expand(TreeItem, TVE_EXPAND); if(m_Tree.ItemHasChildren(TreeItem) != 0) { TreeItem = m_Tree.GetChildItem(TreeItem); while(TreeItem != NULL) { BaumAufklappen(TreeItem); // wow, rekursiv !!! TreeItem = m_Tree.GetNextSiblingItem(TreeItem); } } }
Das Ding ruft sich selbst auf. Für deinen Fall müsstest du es eben anpassen: das Expand kann weg, dafür müsstest du noch das GetItemText(...) an passender Stelle einbauen. Und deine Funktion bräuchte einen zweiten Parameter:
bool CPlanerTestDlg::SearchTree(CString szSearch, HTREEITEM TreeItem)
Von der Funktionalität würde sich wohl nix ändern, aber es wäre weniger Code...[edit]
Nur der Vollständigkeit halber:
das da oben ist keine perfekte Musterlösung sondern nur ein Beispiel. Das Aufklappen geht von innen nach aussen noch schneller, habe ich hier irgenwann einmal gehört.
[/edit]
-
So... hab jetzt ncoh einen kleinen Fehler entdeckt:
Ich kann, falls das Item 2 mal vorkommt, nicht einfache weiter danach suchen!So sieht meine Hierchie aus:
4. Prüfungsfach Deutsch Wurst, Hans Lustig, Peter Chemie Duck, Donald 5. Prüfungsfach Mathe Wurst, Hans
Jetzt müsste ich es noch irgendwie schaffen, das er im 5. Prüfungsfach weiter sucht.