楼上说的方法可以,
我觉得还应加上节点数据类型,可以定义这样一个数据结构:
typdef struct {
   BYTE Depth;//节点深度对于根来说为0
   BYTE Index;//节点序号,仅仅对同一级的节点有用,
   BYTE iCount;//该节点下面有多少个子节点
   BYTE Type;//节点数据类型,如果节点的内容不一样时候有用
   BYTE TxtLen;//节点文字长度,动态申请内存时候用,读取时也要用
   char *pStr;//使用动态指针,以节省空间.申请Txtlen的空间
   BYTE NextType;//下一个节点类型或者说下一个节点是子节点还是兄弟节点
}
文件开始存储节点的总个数N
以后按照上书格式存储
注意存储时候要按照树的遍历存储,
即:
即:首先是根节点,然后是根节点第一个子节点的所有信息;
第二个子节点的所有信息
......

解决方案 »

  1.   

    //这是我最近编写的代码
    UINT CLeftView::GetItemIndentLevel(HTREEITEM hitem)
    {
    int iindent=0;
    CTreeCtrl& rTreeCtrl=GetTreeCtrl();
    while((hitem=rTreeCtrl.GetParentItem(hitem))!=NULL)
    iindent++;
        return iindent;
    }HTREEITEM CLeftView::GetNextItem(HTREEITEM hitem)
    {
    CTreeCtrl& rTreeCtrl=GetTreeCtrl();
    HTREEITEM hti;
    if(rTreeCtrl.ItemHasChildren(hitem))
    return rTreeCtrl.GetChildItem(hitem);
    else
    {
    while((hti=rTreeCtrl.GetNextSiblingItem(hitem))==NULL)
    {
    if((hitem=rTreeCtrl.GetParentItem(hitem))==NULL)
    return NULL;
    }
    }
    return hti;
    }void CLeftView::PreSaveData(void)
    {
    CTreeCtrl& rTreeCtrl=GetTreeCtrl();
    CCDMTDoc* pDoc=GetDocument();
    int i=0;
    HTREEITEM hti,root;
    hti=rTreeCtrl.GetRootItem();
    root=hti;
    while(!(pDoc->m_NodeList.IsEmpty()))
    {
    delete (ZNode*)(pDoc->m_NodeList.RemoveHead());
    } while(hti)
    {
    ZNode *node=new ZNode;
    node->m_nID=i;
    node->m_nPID=0;
    node->m_nLevel=GetItemIndentLevel(hti);
    node->m_strName=rTreeCtrl.GetItemText(hti);
    if(hti==root)
    pDoc->m_NodeList.AddHead(node);
    else
    pDoc->m_NodeList.AddTail(node);
    hti=GetNextItem(hti);
    i++;
    }
    }void CLeftView::CompDataLoad(void)
    {
    CTreeCtrl& rTreeCtrl = GetTreeCtrl();
    CCDMTDoc* pDoc = GetDocument();
    //int i = 0;
    HTREEITEM hti=NULL;
    ZNode *node=NULL;
    POSITION pos=pDoc->m_NodeList.GetHeadPosition();
    if(!(pDoc->m_NodeList.IsEmpty()))
    {
    do
    {
    HTREEITEM parent;
    node=(ZNode*)(pDoc->m_NodeList.GetNext(pos));
    int indent=node->m_nLevel;
    int previndent=GetItemIndentLevel(hti);
    if(indent==previndent)
    parent=rTreeCtrl.GetParentItem(hti);
    else if(indent>previndent)
    parent=hti;
    else
    {
    int nlevelsup=previndent-indent;
    parent=rTreeCtrl.GetParentItem(hti);
    while(nlevelsup--)
    parent=rTreeCtrl.GetParentItem(parent);
    }
    hti=rTreeCtrl.InsertItem(node->m_strName,parent?parent:TVI_ROOT,TVI_LAST);
    }while(pos);
    }
    }
    void CCDMTDoc::Serialize(CArchive& ar)
    {
    //m_NodeList.Serialize(ar);
    CLeftView * pView=(CLeftView *)MyGetView(RUNTIME_CLASS(CLeftView));
     //   pView->MyLeftViewMsgBox();
    //pView->MyTest2();
    if (ar.IsStoring())
    {
    // TODO:在此添加存储代码
    pView->PreSaveData();
    m_NodeList.Serialize(ar);
    }
    else
    {
    // TODO:在此添加加载代码
    m_NodeList.Serialize(ar);
    pView->CompDataLoad();
    UpdateAllViews(NULL);
    }
    }
    CView * CCDMTDoc::MyGetView(CRuntimeClass * pClass)
    {
    CView* pView;
    POSITION pos=GetFirstViewPosition();
    while(pos!=NULL)
    {
    pView=GetNextView(pos);
    if(pView->IsKindOf(pClass))
    break;
    }
    if(!pView->IsKindOf(pClass))
    return  NULL;
    return pView;
    }
      

  2.   

    请问楼上:m_NodeList是自定义的节点类型吗?