由于编写一个电子地图程序时,要保存一些地图信息到文件中,而地图保存方式是树的形式,因此遇到一个如何树项对应的内容,在程序运行时能完整地重画出来。我是这样实现的:
首先确定保存树的顺序,我是用先序遍历,然后设置标置确实后面的数据是那个树元素的。
#define FLAG_BENGIN 0xff
#define FLAG_END 0xfe
#define FLAG_CHILD 0xfd
#define FLAG_SILBING 0xfc
#define FLAG_NEXTGROUP 0xfb
#define FLAG_DATA 0xfa
采用递归的方式把树写放文件中:
void CMapTree::WriteBranch2File(HTREEITEM hItem, FILE *hf)
{
CString str = this->GetItemText(hItem);
int size;
保存数据
HTREEITEM RootItem = GetRootItem();
if (hItem != RootItem) {
BYTE flag = FLAG_DATA;
size = fwrite(&flag,sizeof(BYTE),1,hf);
TRACE("fwrite size %d",size);
int index;
if (GetMapInfoByName(str, &index)) {
MAPINFOHEAD head = g_pMapinfoArray.GetAt(index)->head;
size = fwrite(&head,sizeof(MAPINFOHEAD),1,hf);
TRACE("fwrite size %d",size);
DWORD Hostcount = g_pMapinfoArray.GetAt(index)->HostCount;
size = fwrite(&Hostcount, sizeof(DWORD),1,hf);
TRACE("fwrite size %d",size);
for(int i = 0; i<(int)Hostcount; i++)
{
HOSTWNDINFO hostwnd = g_pMapinfoArray.GetAt(index)->HostWndArray.GetAt(i);
size = fwrite(&hostwnd,sizeof(HOSTWNDINFO),1,hf);
TRACE("fwrite size %d",size);
}
DWORD AlarmCount = g_pMapinfoArray.GetAt(index)->AlarmWndCount;
size = fwrite(&AlarmCount, sizeof(DWORD),1, hf);
TRACE("fwrite size %d",size);
for(i = 0; i < (int)AlarmCount; i++)
{
ALARMWNDINFO alarmwnd = g_pMapinfoArray.GetAt(index)->AlarmWndArray.GetAt(i);
size = fwrite(&alarmwnd, sizeof(ALARMWNDINFO), 1, hf);
TRACE("fwrite size %d",size);
}
}// end of if
} //end of if
TRACE(str);
HTREEITEM chItem = this->GetChildItem(hItem);
if (chItem != NULL) {
BYTE flag = FLAG_CHILD;
size = fwrite(&flag,sizeof(BYTE),1,hf);
TRACE("fwrite size %d",size);
TRACE("Child");
WriteBranch2File(chItem,hf);
}
HTREEITEM Sibling = this->GetNextSiblingItem(hItem);
if (Sibling != NULL) {
BYTE flag = FLAG_SILBING;
size = fwrite(&flag,sizeof(BYTE),1,hf);
TRACE("fwrite size %d",size);
TRACE("Silbing");
WriteBranch2File(Sibling,hf);
}else
{
BYTE flag = FLAG_NEXTGROUP;
size = fwrite(&flag,sizeof(BYTE),1,hf);
TRACE("fwrite size %d",size);
TRACE("LoadTree End");
}
}
相反把树读出来:
void CMapTree::LoadTreeAndDraw(FILE *hf)
{
BOOL bEnd = FALSE;
HTREEITEM hParent = GetRootItem();
enum {Child,Silbing,NextGroup,Root} BranchType;
BranchType = Root;
PMAPINFO MapInfo;
MAPINFOHEAD head;
DWORD hostcount;
HOSTWNDINFO hostwnd;
DWORD AlarmWndcount;
ALARMWNDINFO alarmwnd;
int i;
CString szItem;
BYTE flag;
read first flag
fread(&flag,sizeof(BYTE),1,hf);
while (!bEnd) {
switch(flag) {
case FLAG_BENGIN:
fread(&flag,sizeof(BYTE),1,hf);
break;
case FLAG_DATA:
MapInfo = new MAPINFO;
read head
fread(&head,sizeof(MAPINFOHEAD),1,hf);
MapInfo->head =head;
read HostWndArray
fread(&hostcount,sizeof(DWORD),1,hf);
MapInfo->HostCount = hostcount;
for(i = 0; i<(int)hostcount;i++)
{
fread(&hostwnd,sizeof(hostwnd),1,hf);
MapInfo->HostWndArray.Add(hostwnd);
}
read AlarmWndArray
fread(&AlarmWndcount,sizeof(DWORD),1,hf);
MapInfo->AlarmWndCount = AlarmWndcount;
for(i = 0; i <(int)AlarmWndcount; i++)
{
fread(&alarmwnd, sizeof(ALARMWNDINFO),1,hf);
MapInfo->AlarmWndArray.Add(alarmwnd);
}
add mapInfo
g_pMapinfoArray.Add(MapInfo);
Draw Tree
switch(BranchType) {
case Child:
szItem = MapInfo->head.chMapName;
hParent = InsertItem(szItem,0,1,hParent,TVI_LAST);
break;
case Silbing:
szItem = MapInfo->head.chMapName;
hParent = GetParentItem(hParent);
hParent = InsertItem(szItem,0,1,hParent,TVI_LAST);
break;
/* case NextGroup:
hParent = GetParentItem(hParent);
break;*/
case Root:
default:
break;
}
read flag
fread(&flag,sizeof(BYTE),1,hf);
break; end of FLAG_DATA
case FLAG_CHILD:
BranchType = Child;
fread(&flag,sizeof(BYTE),1,hf);
break;
case FLAG_SILBING:
BranchType = Silbing;
fread(&flag,sizeof(BYTE),1,hf);
break;
case FLAG_NEXTGROUP:
hParent = GetParentItem(hParent);
//BranchType = NextGroup;
fread(&flag,sizeof(BYTE),1,hf);
break;
case FLAG_END:
bEnd = TRUE; 文件读完
break;
default:
bEnd = TRUE; 读文件异常退出
break;
}
}
}