CTreeCtrl - Unterknoten hinzufügen



  • Anscheinend ist meine Frage einfach zu trivial, so dass ich mit der Suchfunktion hier im Forum (habe alle CTreeCtrl Beiträge durchgelesen) als auch über Google keine Lösung finden konnte. 😞

    Ich möchte lediglich einem Knoten einen Unterknoten hinzufügen.

    Hiermit füge ich einen Eintrag hinzu:

    m_ctlTreeCtrl.InsertItem("Knoten");
    

    Wie kann ich nun "Unterknoten" hinzufügen, so dass das dann z.B. so aussieht:

    Knoten A
        Unterknoten 1
            UnterUnterknoten I
            UnterUnterknoten II
        Unterknoten 2
        Unterknoten 3
    Knoten B
        Unterknoten 1
        ...
    

    Würd mich freuen, wenn mir jemand helfen könnte!



  • Mit folgendem Code kannst du ein Wurzelelement, sein Kindelement und ein Kindelement des Kindelements hinzufügen.

    TVINSERTSTRUCT TvStruct;
        TVITEMEX       &TvItemEx = TvStruct.itemex;
        HTREEITEM      hTreeItem = 0;
    
        TvStruct.hParent      = NULL;
        TvStruct.hInsertAfter = TVI_ROOT;
    
        TvItemEx.mask = TVIF_TEXT;
        TvItemEx.pszText = "Wurzelelement";
    
        if ((hTreeItem = TreeView.InsertItem(&TvStruct)) == NULL)
        {
            // Fehler
        }
    
        TvStruct.hParent      = hTreeItem;
        TvStruct.hInsertAfter = TVI_LAST;
    
        TvItemEx.pszText = "Kindelement von Wurzelelement";
    
        if ((hTreeItem = TreeView.InsertItem(&TvStruct)) == NULL)
        {
            // Fehler
        }
    
        TvItemEx.pszText ="Unterknoten -> Kindelement";
        TvStruct.hParent = hTreeItem;
    
        if (TreeView.InsertItem(&TvStruct) == NULL)
        {
            // Fehler
        }
    

    Also hParent einfach immer das Handle des Elternknotens eintragen. Das wars schon.



  • Danke! Das Beispiel compiliert ohne Fehler! Allerdings zeigt er nur "Wurzelement" an, sonst nichts! Für alle if Anweisungen ergibt es FALSE, somit scheint ja alles glatt zu gehen. Woran kann es liegen? Ich habe statt "TreeView" immer meinen CTreeCtrl "m_ctlTreeCtrl" angegeben.



  • Hab immernoch nicht hinbekommen. Aber ich betrachte jetzt mal nur das Minimum:

    HTREEITEM hRoot = m_ctlTreeCtrl.InsertItem("Root", TVI_ROOT);
    	HTREEITEM hChild = m_ctlTreeCtrl.InsertItem("Child1", hRoot);
    	HTREEITEM hChild2 = m_ctlTreeCtrl.InsertItem("Child2", hRoot);
    	HTREEITEM hChildChild = m_ctlTreeCtrl.InsertItem("ChildChild", hChild);
    

    Sollte doch eigentlich das ergeben:

    Root
    |
    +--Child1
    | |
    | +--ChildChild
    |
    +--Child2

    Aber auch hier steht nachher nur "Root" im CTreeCtrl! Weiss jemand Rat?



  • Ok, ich nehm alles zurück und behaupte das Gegenteil 🤡

    Funktioniert. Wusste nur nicht, dass Standardmäßig keine Icons dabei sind.



  • plizer schrieb:

    Sollte doch eigentlich das ergeben:

    Root
    |
    +--Child1
    | |
    | +--ChildChild
    |
    +--Child2

    Nein aber das hier. 😉

    +--Root
       |
       +--Child1
       |         |
       |        +--ChildChild
       |
       +--Child2
    

    plizer schrieb:

    Ok, ich nehm alles zurück und behaupte das Gegenteil 🤡

    Funktioniert. Wusste nur nicht, dass Standardmäßig keine Icons dabei sind.

    Meinst du Icons für jewilgen Knoten oder die Plus-/Minuszeichen? Die müssen natrülich per Flag gesetzt werden.



  • Ich hatte einfach nicht gemerkt, dass ein Baum aufgebaut wurde. Als nächsten muss ich jetzt mal schauen, wie das mit den Bildern geht. Danke für Deine Hilfe!



  • plizer schrieb:

    Ich hatte einfach nicht gemerkt, dass ein Baum aufgebaut wurde. Als nächsten muss ich jetzt mal schauen, wie das mit den Bildern geht. Danke für Deine Hilfe!

    Das ist auch kein Problem. Du weist dem TreeView eine ImageList mit SetImageList zu. Füllst diese mit Bildern.

    Beim hinzufügen von TreeView Items muss du dann das Flag TVIF_IMAGE in der Itemstruktur setzen (mask Member) und weist dem iImage Member den Index des Bildes in der ImageList zu.



  • Gibt es eine Möglichkeit zu erfragen, ob ein string schon als Unterknoten verhanden ist? Ich muss nämlich aus einer liste von strings einen Baum erstellen.
    Aus:

    A12
    A15
    A16
    A21
    A23
    A30
    B12
    B13
    B23
    C34
    

    soll werden:

    A
    +-- 1
        +-- 2
        +-- 5
        +-- 6
    +-- 2
        +-- 1
        +-- 3
    +-- 3
        +-- 0
    B
    +-- 1
        +-- 2
        +-- 3
    +-- 2
        +-- 3
    C
    +-- 3
        +-- 4
    

    Dazu muss ich nun wissen, ob ein Unterknoten ein string enthält, nur weiss ich nicht wie ich an die strings kommen soll in den nodes!

    Kannst Du mir da nen Tipp geben?



  • plizer schrieb:

    Kannst Du mir da nen Tipp geben?

    Eine Methode in CTreeCtrl dafür gibt es nicht. Du müsstest beim hinzufügen von Knoten vorher die vorhanden durchlaufen und prüfen ob "der Neue" schon existiert. Falls nicht fügst du ihn hinzu.



  • HaJo. schrieb:

    plizer schrieb:

    Kannst Du mir da nen Tipp geben?

    Eine Methode in CTreeCtrl dafür gibt es nicht. Du müsstest beim hinzufügen von Knoten vorher die vorhanden durchlaufen und prüfen ob "der Neue" schon existiert. Falls nicht fügst du ihn hinzu.

    Genau so wollte ich das machen! Allerdings weiss ich nicht, wie ich an den string eines vorhandenen Knoten kommen kann! Ich bekomme ja immer nur an HTREEITEM dran.



  • plizer schrieb:

    Genau so wollte ich das machen! Allerdings weiss ich nicht, wie ich an den string eines vorhandenen Knoten kommen kann! Ich bekomme ja immer nur an HTREEITEM dran.

    Mit GetNextSiblingItem / GetPrevSiblingItem kannst du die Items durchwandern. und mit GetItemText erhälst du einen CString mit dem zugehörigen Text welchen du mit Compare vergleichen könntest.



  • HaJo. schrieb:

    plizer schrieb:

    Genau so wollte ich das machen! Allerdings weiss ich nicht, wie ich an den string eines vorhandenen Knoten kommen kann! Ich bekomme ja immer nur an HTREEITEM dran.

    Mit GetNextSiblingItem / GetPrevSiblingItem kannst du die Items durchwandern. und mit GetItemText erhälst du einen CString mit dem zugehörigen Text welchen du mit Compare vergleichen könntest.

    Danke für Deine Unterstützung! 🙂 Mit den Daten sollte ich es dann hinbekommen!



  • Ich kanns nicht glauben, dass ich nach mindestens 2 Manntage es immer noch nicht hinbekommen habe, in einem CTreeCtrl zu schauen, ob ein Unterknoten mit einem bestimmten string vorhanden ist und falls nicht, diesen einzufügen.

    Ich habe mir alle interessanten MSDN Beispiele zum CTreeCtrl angeschaut und alles versucht. Aber die Beispiele entbehren sich für mich jeder Logik, so dass ich da einfach nichts hinbekomme.
    Beispiel:

    HTREEITEM hmyItem;
    if (pmyTreeCtrl->ItemHasChildren(hmyItem))
    {
    ...
    

    hmyItem ist doch undefiniert. Wie kann ich dann anschließend einer Methode ein undefiniertes Objekt (bzw. eine Kopie) in der Parameterliste übergeben? Oder wird hmyItem ein neuer Wert zugeordnet? (Weil anschließend damit weitergearbeitet wird) Wenn das so ist, werde ich das wohl nie wirklich verinnerlichen, weil ich das für mich sehr unlogisch ist.

    😞



  • plizer schrieb:

    hmyItem ist doch undefiniert. Wie kann ich dann anschließend einer Methode ein undefiniertes Objekt (bzw. eine Kopie) in der Parameterliste übergeben? Oder wird hmyItem ein neuer Wert zugeordnet? (Weil anschließend damit weitergearbeitet wird) Wenn das so ist, werde ich das wohl nie wirklich verinnerlichen, weil ich das für mich sehr unlogisch ist.:(

    Der Parameter hItem müsste ein Handle auf das TreeView Item sein, bei dem du die Kinderprüfung durchführen möchtest.



  • HaJo. schrieb:

    plizer schrieb:

    hmyItem ist doch undefiniert. Wie kann ich dann anschließend einer Methode ein undefiniertes Objekt (bzw. eine Kopie) in der Parameterliste übergeben? Oder wird hmyItem ein neuer Wert zugeordnet? (Weil anschließend damit weitergearbeitet wird) Wenn das so ist, werde ich das wohl nie wirklich verinnerlichen, weil ich das für mich sehr unlogisch ist.:(

    Der Parameter hItem müsste ein Handle auf das TreeView Item sein, bei dem du die Kinderprüfung durchführen möchtest.

    Danke! Hast Du dazu vielleicht einen Link wo ich Infos dazu bekomme? Ich habe zwar schon einige gute C++ Bücher hier, aber zu handles steht da nirgend etwas.

    PS: Sieben Bücher und insgesamt über 5000 Seiten und keinmal das Wort handle. Wieder einmal etwas, was ich nicht verstehe.



  • plizer schrieb:

    Danke! Hast Du dazu vielleicht einen Link wo ich Infos dazu bekomme? Ich habe zwar schon einige gute C++ Bücher hier, aber zu handles steht da nirgend etwas.

    Zu Handles oder wie du weiter vorgehen müsstest?

    PS: Sieben Bücher und insgesamt über 5000 Seiten und keinmal das Wort handle. Wieder einmal etwas, was ich nicht verstehe.[/quote]
    http://de.wikipedia.org/wiki/Handle



  • Am besten natürlich wie ich auch weiterkomme. Aber ich mags ja selbst nicht, wenn sich Leute was verkauen lassen. Also bin ich auch nicht böse wenn mir keiner hilft ;). Obwohl, lange genug sitz ich ja schon dran.

    Aber was meinst Du genau mit:

    Der Parameter hItem müsste ein Handle auf das TreeView Item sein, bei dem du die Kinderprüfung durchführen möchtest.

    Ich will also schauen, ob im CTreeCtrl ein Eintrag vorhanden ist.

    Ich lege die Items folgendermaßen an:

    HTREEITEM hRoot = m_ctlTreeCtrl.InsertItem("Wurzel", TVI_ROOT);
    HTREEITEM h1 = m_ctlTreeCtrl.InsertItem("Unterknoten", hRoot);
    HTREEITEM h2 = m_ctlTreeCtrl.InsertItem("UUnterknoten".c_str(), h1);
    HTREEITEM h3 = m_ctlTreeCtrl.InsertItem("UUUnterknoten".c_str(), h2);
    HTREEITEM h4 = m_ctlTreeCtrl.InsertItem("UUUUnterknoten".c_str(), h3);
    

    Wie kann ich nun z.B. rausfinden ob unter der "Wurzel" der Eintrag "Unterknoten" verhanden ist. Oder halt ob bei "UUUnterknoten" "UUUUnterknoten" enthalten ist.

    Da ich erst später nachfrage, kenne ich in dem Moment nicht hRoot oder h1 usw., sondern muss die Information aus dem CTreeCtrl bekommen, nur wie?



  • plizer schrieb:

    Da ich erst später nachfrage, kenne ich in dem Moment nicht hRoot oder h1 usw., sondern muss die Information aus dem CTreeCtrl bekommen, nur wie?

    Kurze Verständnisfrage. Legst du alle Elemente erst an - auch doppelte - und prüfst "irgendwann" später oder möchtest du beim Anlegen immer gleich prüfen ob ein Knoten mit dem String X schon existiert?



  • Ich bekomme die einzelnen Strings aus einer Datenbank, die vereinfacht so aussehen:

    A12
    A15
    A16
    A21
    A23
    A30
    B12
    B13
    B23
    C34
    

    Daraus soll dann der unten dargestellte Baum werden. Ich habe den String schon aufgeteilt, so dass ich 5 Variablen habe, die bis zu 5 Ebenen tief gehen. Natürlich soll er das A am Anfang z.B. nur einmal anlegen, wenn es da ist, kann er direkt den Unterpunkt einfügen, aber natürlich nur falls dieser auch noch nicht da ist usw.
    Algorithmisch gesehen macht mir das keine Probleme, aber ich kann mit dem CTreeCtrl überhaupt nicht umgehen!

    A
    +-- 1
        +-- 2
        +-- 5
        +-- 6
    +-- 2
        +-- 1
        +-- 3
    +-- 3
        +-- 0
    B
    +-- 1
        +-- 2
        +-- 3
    +-- 2
        +-- 3
    C
    +-- 3
        +-- 4
    

Anmelden zum Antworten