Немогу разобраться как сохранить CTreeCtrl в файл.
Вроде бы в меню SDI приложения же ессть меню сохранить
и класс стандартный поддерживает сериализацию.
Вобщем объясните как что нужно делать.
Здравствуйте 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);
}
}
Чтение по образу и подобию.
Здравствуйте 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 перегнать в ихнее дерево.