Baumhierarchien (CTreeCtrl) Serializen



  • Hallo!
    Folgende Situation:
    Ich habe ein CTreeCtrl, welches unendlich viele Knoten haben kann. Es kann zwei Objekte enthalten. Einmal Objekt A und Objekt B. Jedes Objekt enthält seinen Namen und seinen eigenen Pfad (also einfach 2 Strings). Objekt A ist in der Lage unendlich viele Unterobjekte (egal welchen Types zu enthalten). Objekt B jedoch nicht! Dieses darzustellen und zum implementieren ist kein großes Problem. Jedoch das Serializen...mhh ich hätte schon ein paar Ideen, jedoch hat jemand von euch etwas bahnbrechenderes 🙂

    Danke

    Kevin



  • Das sollte funktionieren:

    Aufruf: save_tree(ar,treeCtrl,treeCtrl.GetRootItem());

    void save_tree(CArchive& ar,const CTreeCtrl& tree,HTREEITEM curItem)
    {
    	while(curItem)
    	{
    		bool hasChilds = 0 != tree.ItemHasChildren(curItem);
    		ar.Write(&hasChilds,sizeof hasChilds);
    		ar << tree.GetItemText(curItem);
    		// ar << Deine Daten
    		if(hasChilds)
    			save_tree(ar,tree,tree.GetChildItem(curItem));
    		curItem = tree.GetNextSiblingItem(curItem);
    	}
    }
    


  • Hallo!
    Erstmal danke, so hatte ich das ebenfalls vor. Jedoch gibt es dann ein Problem beim Auslesen, da die Objekte nicht mehr wissen wer ihre Eltern sind. Dies könnte man über IDs lösen. Jedoch gibt es da auch einige Probleme. Wenn hier keine super Lösung kommt mache ich das einfach mit Hilfe der Windowsordner. ObjektA bekommt nen Ordner und eine Datei mit dem ObjektA Namen, in dieser Datei stehen alle Pfade zu den ObjektBs, wenn es Unterobjekte hat werden einfach Unterordner erstellt.
    Was meint ihr?

    Kevin



  • Das Einlesen hatte ich ganz vergessen. 🙂

    Das hier funktioniert jetzt:

    void save_tree(CArchive& ar,const CTreeCtrl& tree,HTREEITEM curItem)
    {
    	while(curItem)
    	{
    		char childID;
    		childID = tree.ItemHasChildren(curItem) ? beginchild : nochild;
    		ar << childID << tree.GetItemText(curItem);
    		// ar << Deine Daten
    		if(childID == beginchild)
    			save_tree(ar,tree,tree.GetChildItem(curItem));
    		curItem = tree.GetNextSiblingItem(curItem);
    	}
    	ar << static_cast<char> (endchild);
    }
    
    inline char read_id(CArchive& ar)
    {
    	char id;
    	ar >> id;
    	return id;
    }
    
    void load_tree(CArchive& ar,CTreeCtrl& tree,HTREEITEM parent = 0)
    {
    	char childID;
    	while((childID = read_id(ar)) != endchild)
    	{
    		CString text;
    		ar >> text;
    		// ar >> Deine Daten
    		HTREEITEM item = tree.InsertItem(text,parent);
    		if(childID == beginchild)
    			load_tree(ar,tree,item);
    	}
    }
    

    Aber ich persönlich würde das nicht so machen. Was wenn du kein TreeCtrl mehr verwenden willst? Dann musst vieles verändern. Ich würde mir einen Baum mit einer Klasse aufbauen.

    z.B.

    class item
    {
    	CString title;
    	// Daten...
    
    	CArray<item*,item*> childs;
    };
    

    Und dieses dann abspeichern/laden.



  • HI!
    Erstmal danke!
    Du hast Recht, wenn kein CTreeCtrl mehr benötigt wird ist es umständlich. Deshalb versuche ich es erstmal mit der Ordnerhierarchie zu speichern denke ich....mal sehen wie das klappt!

    Kevin


Log in to reply