Как сохранить CTreeCtrl в файл
От: IceHand  
Дата: 16.10.02 03:23
Оценка:
Немогу разобраться как сохранить CTreeCtrl в файл.
Вроде бы в меню SDI приложения же ессть меню сохранить
и класс стандартный поддерживает сериализацию.
Вобщем объясните как что нужно делать.
Re: Как сохранить CTreeCtrl в файл
От: Stanislav V. Zudin Россия  
Дата: 16.10.02 06:20
Оценка:
Здравствуйте IceHand, Вы писали:

IH>Немогу разобраться как сохранить CTreeCtrl в файл.

IH>Вроде бы в меню SDI приложения же ессть меню сохранить

Есть. По-умолчанию вызывается CYourDocument::OnSaveDocument

IH>и класс стандартный поддерживает сериализацию.


Кто, дерево? Не, оно сериализацию не поддерживает.

IH>Вобщем объясните как что нужно делать.


Написать функцию, которая будет обегать твое дерево и сохранять все данные в CArchive. Какие данные нужно сохранять и в каком виде — известно только тебе. Будет что-то вроде...

void SerializeTree(HTREEITEM hti, CArchive& ar)
{
   CString text = your_tree.GetItemText(hti); // не помню синтаксиса MFC-шного дерева, извиняй
   ar << text;
   DWORD data = your_tree.GetItemData(hti); 
   ar << data;
   // Сохранить чего-нибудь еще
   ...
   // Сохранить кол-во детей
   int childnum = your_tree.GetChildrenCount(hti); // ну не помню точного имени функции
   ar << childnum;
   // сохранить каждого из дитёнков
   HTREEITEM hchild = your_tree.GetChildItem(hti);
   while(hchild != NULL)
   {
      SerializeTree(hchild, ar);
      hchild = your_tree.GetNextSiblingItem(hti);
   }
}


Чтение по образу и подобию.
_____________________
С уважением,
Stanislav V. Zudin
Re: Как сохранить CTreeCtrl в файл
От: Patalog Россия  
Дата: 16.10.02 09:01
Оценка:
Здравствуйте IceHand, Вы писали:

IH>Немогу разобраться как сохранить CTreeCtrl в файл.

IH>Вроде бы в меню SDI приложения же ессть меню сохранить
IH>и класс стандартный поддерживает сериализацию.
IH>Вобщем объясните как что нужно делать.

Меню сохранить относится к досументу. При чем tyt CTreeCtrl? У него нет метода Serialize... Но ничто не мешает тебе сделать его самому.
Типа того:
//.h Объявления...
class CTreeItem : public CObject
{
public:
    CTreeItem() { }
    CTreeItem(const TVITEM& tv_item) { Attach(tv_item); }
    CTreeItem(const CTreeItem& item)
    {
        mask = item.mask;
        state = item.state;
        state_mask = item.state_mask;
        text = item.text;
        text_max = item.text_max;
        image = item.image;
        sel_image = item.sel_image;
        child_count = item.child_count;
        param = item.param;
    }
    
    void Attach(const TVITEM& tv_item)
    {
        mask = tv_item.mask;
        state = tv_item.state;
        state_mask = tv_item.stateMask;
        text = tv_item.pszText;
        text_max = tv_item.cchTextMax;
        image = tv_item.iImage;
        sel_image = tv_item.iSelectedImage;
        child_count = tv_item.cChildren;
        param = tv_item.lParam;
    }

    void Serialize(CArchive&);

    DECLARE_SERIAL(CTreeItem)

    UINT        mask;
    UINT        state;
    UINT        state_mask;
    CString        text;
    int            text_max;
    int            image;
    int            sel_image;
    int            child_count;
    LPARAM        param;

};

//.cpp Определения....
IMPLEMENT_SERIAL(CTreeItem, CObject, VERSIONABLE_SCHEMA)

void CTreeItem::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        ar 
            << mask 
            << state 
            << state_mask 
            << text 
            << text_max 
            << image 
            << sel_image 
            << child_count 
            << param;
    }
    else
    {
        ar 
            >> mask 
            >> state 
            >> state_mask 
            >> text 
            >> text_max 
            >> image 
            >> sel_image 
            >> child_count 
            >> param;
    }
}

CTreeItem GetTreeItem(CTreeCtrl& tree, HTREEITEM item)
{
    TVITEM tv_item = { 0 };
    tv_item.hItem = item;
    tv_item.mask = TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
    TCHAR text[MAX_PATH] = { 0 };
    tv_item.pszText = text;
    tv_item.cchTextMax = MAX_PATH;
    tree.GetItem(&tv_item);
    if(tv_item.cChildren > 0) {
        int child_count = 0;
        HTREEITEM child = tree.GetNextItem(item, TVGN_CHILD);
        while(child) {
            ++child_count;
            child = tree.GetNextItem(child, TVGN_NEXT);
        }

        tv_item.cChildren = child_count;
    }

    return CTreeItem(tv_item);
}

void SerializeAll(CTreeCtrl& tree, HTREEITEM item, CArchive& ar)
{
    if (ar.IsStoring())
    {
        while(item) {
            CTreeItem s_item = GetTreeItem(tree, item);
            s_item.Serialize(ar);
            HTREEITEM child = tree.GetNextItem(item, TVGN_CHILD);
            SerializeAll(tree, child, ar);
            item = tree.GetNextItem(item, TVGN_NEXT);
        }
    }
    else
    {
        CTreeItem s_item;
        s_item.Serialize(ar);
        HTREEITEM next = tree.InsertItem(s_item.text, s_item.image, s_item.sel_image, item);
            
        for(int i = 0; i < s_item.child_count; ++i) 
            SerializeAll(tree, next, ar);

    }
}

void CTestDoc::Serialize(CArchive& ar)
{
    POSITION pos = GetFirstViewPosition();
    MyTreeView* my_view = static_cast<MyTreeView*>(GetNextView(pos));
    CTreeCtrl& tree = my_view->GetTreeCtrl();

    if (ar.IsStoring())
    {
        int root_count = 1;
        HTREEITEM root = tree.GetRootItem();
        while(root = tree.GetNextItem(root, TVGN_NEXT))
            ++root_count;
        ar << root_count;

        root = tree.GetRootItem();
        SerializeAll(tree, root, ar);
    }
    else
    {
        tree.DeleteAllItems();

        int root_count = 0;
        ar >> root_count;
        for(int i = 0; i < root_count; ++i)
            SerializeAll(tree, TVI_ROOT, ar);
    }
}


На красоту не претендует, но думаю идея понятна...
А вообще для етой цели можно заюзать Boost, там ето сделано (в смысле персистенстность объектов, в частности деревьев). Останется только TreeCtrl перегнать в ихнее дерево.
Почетный кавалер ордена Совка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.