⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 persistenttreectrl.cpp

📁 两个有关xml文件的操作类
💻 CPP
字号:
// PersistentTreeCtrl.cpp : implementation file
//

#include "stdafx.h"

#include "PersistentTreeCtrl.h"

#include <algorithm>
#include <cassert>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

const int MAXTEXTLEN=1024;

/////////////////////////////////////////////////////////////////////////////
// CPersistentTreeCtrl

CPersistentTreeCtrl::CPersistentTreeCtrl()
{
}

CPersistentTreeCtrl::~CPersistentTreeCtrl()
{
}

BEGIN_MESSAGE_MAP(CPersistentTreeCtrl, CTreeCtrl)
	//{{AFX_MSG_MAP(CPersistentTreeCtrl)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPersistentTreeCtrl message handlers

void CPersistentTreeCtrl::SetImage(UINT id_bitmap)
{
	if(m_imagelist.m_hImageList==NULL)
		m_imagelist.Create(id_bitmap,16, 16, RGB(0, 0x80, 0x80));
	else
	{
		m_imagelist.DeleteImageList();
		m_imagelist.Create(id_bitmap,16, 16, RGB(0, 0x80, 0x80));
	}
	this->SetImageList(&m_imagelist, TVSIL_NORMAL);
}

void CPersistentTreeCtrl::InitTestItems()
{	
	HTREEITEM root = InsertItem("中华人民共和国",0,0);
	HTREEITEM subroot1=InsertItem("浙江",1,1,root);
	HTREEITEM subroot2=InsertItem("江苏",1,1,root);
	HTREEITEM subroot3=InsertItem("安徽",1,1,root);
	HTREEITEM subroot4=InsertItem("江西",1,1,root);
	HTREEITEM subroot5=InsertItem("福建",1,1,root);
	HTREEITEM subroot6=InsertItem("上海",1,1,root);

	HTREEITEM subroot_SX=InsertItem("绍兴",2,2,subroot1);
	InsertItem("嵊州",3,3,subroot_SX);
	InsertItem("新昌",3,3,subroot_SX);
	InsertItem("东阳",3,3,subroot_SX);

	InsertItem("温州",2,2,subroot1);
	InsertItem("萧山",2,2,subroot1);
	InsertItem("衢州",2,2,subroot1);
	
	InsertItem("常州",2,2,subroot2);
	InsertItem("苏州",2,2,subroot2);
	InsertItem("无锡",2,2,subroot2);
	InsertItem("徐州",2,2,subroot2);


	InsertItem("合肥",2,2,subroot3);	
	InsertItem("安庆",2,2,subroot3);
	
	InsertItem("吉安",2,2,subroot4);

	InsertItem("福州",2,2,subroot5);
	InsertItem("厦门",2,2,subroot5);
	
	//SelectItem(root);
	//Expand(root, TVE_EXPAND);

	root = InsertItem("美国",0,0);
	InsertItem("加州",1,1,root);
	InsertItem("宾州",1,1,root);
	/*
	Expand(subroot1, TVE_EXPAND);
	Expand(subroot2, TVE_EXPAND);
	Expand(subroot3, TVE_EXPAND);
	Expand(subroot4, TVE_EXPAND);
	Expand(subroot5, TVE_EXPAND);*/

}

string CPersistentTreeCtrl::GetAllItemText()
{
	str_msg="";
	TraverseItems();
	return str_msg;
}

//traverse all items, DFS method
HTREEITEM CPersistentTreeCtrl::TraverseItems(HTREEITEM hItem)
{
	// If hItem is NULL, start search from root item.
	if (hItem == NULL)
		hItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0);
	
	while (hItem != NULL)
	{
		CString str_tree;
		char szBuffer[MAXTEXTLEN+1];
		szBuffer[0]=0;
		
		TV_ITEM item;
		
		item.hItem = hItem;
		item.mask = TVIF_TEXT | TVIF_CHILDREN;
		item.pszText = szBuffer;
		item.cchTextMax = MAXTEXTLEN;
		::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
		str_tree=szBuffer;
		str_tree+=">";//add a separator
		
		str_msg+=str_tree;
		//item_vec.push_back( str_parent+str_tree );
		
		// Check whether we have child items.
		if (item.cChildren)
		{
			// Recursively traverse child items.
			HTREEITEM hItemFound, hItemChild;
			
			hItemChild = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM,
				TVGN_CHILD, (LPARAM)hItem);
			if(hItemChild!=NULL)
				hItemFound = TraverseItems( hItemChild);
			
			// Did we find it?
			if (hItemFound != NULL)
				return hItemFound;
		}
		
		// Go to next sibling item.
		hItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM,
			TVGN_NEXT, (LPARAM)hItem);
	}
	return hItem;
	
}


//have the item any duplicate children?
bool CPersistentTreeCtrl::HasDuplicateChild(HTREEITEM hItem)
{
	string str_tree;
	char szBuffer[MAXTEXTLEN+1];
	szBuffer[0]=0;
	
	TV_ITEM item;
	
	item.hItem = hItem;
	item.mask = TVIF_TEXT | TVIF_CHILDREN;
	item.pszText = szBuffer;
	item.cchTextMax = MAXTEXTLEN;	
	
	std::vector<string> vec;
	std::vector<string>::const_iterator iter;
	int result;

	while (hItem != NULL)
	{	
		item.hItem = hItem;
		::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
		vec.push_back(szBuffer);
		// Go to next sibling item.
		hItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM,
			TVGN_NEXT, (LPARAM)hItem);
	}
	
	for(iter=vec.begin(); iter!= vec.end(); ++iter)
	{
		result=std::count( vec.begin(), vec.end(), *iter );
		if  ( result > 1 )
			return true;//we found it!!
	}

	return false;
}

//has tree any duplicate items?
HTREEITEM CPersistentTreeCtrl::HasDuplicate(HTREEITEM hItem, bool& bDuplicate)
{
	if(hItem ==NULL)
		hItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0);
	
	while (hItem != NULL)
	{
		char szBuffer[MAXTEXTLEN+1];
		szBuffer[0]=0;
		
		TV_ITEM item;
		
		item.hItem = hItem;
		item.mask = TVIF_TEXT | TVIF_CHILDREN;
		item.pszText = szBuffer;
		item.cchTextMax = MAXTEXTLEN;
		::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
	
		if(HasDuplicateChild(hItem))
		{
			bDuplicate=true;
			return NULL;
		}
		
		// Check whether we have child items.
		if (item.cChildren)
		{
			// Recursively traverse child items.
			HTREEITEM hItemFound, hItemChild;
			
			hItemChild = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM,
				TVGN_CHILD, (LPARAM)hItem);
			if(hItemChild!=NULL)
				hItemFound = HasDuplicate( hItemChild, bDuplicate);
			if(bDuplicate==true)
				return NULL;
			
			// Did we find it?
			if (hItemFound != NULL)
				return hItemFound;
		}
		
		// Go to next sibling item.
		hItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM,
			TVGN_NEXT, (LPARAM)hItem);
	}
	return hItem;
}

bool CPersistentTreeCtrl::HasDuplicate()
{
	bool bDuplicate=false;
	HasDuplicate(NULL, bDuplicate);
	return bDuplicate;
}

//traverse all items
HTREEITEM CPersistentTreeCtrl::SaveItems(void* pXmlfile, const char* tree_name, HTREEITEM hItem, string str_parent, bool bImage)
{
	CXMLFile* xmlfile=static_cast<CXMLFile*>(pXmlfile);

	// If hItem is NULL, start search from root item.
	if (hItem == NULL)
		hItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0);
	
	while (hItem != NULL)
	{
		string str_tree;
		char szBuffer[MAXTEXTLEN+1];
		szBuffer[0]=0;
		
		TV_ITEM item;		
		item.hItem = hItem;
		item.mask = TVIF_TEXT| TVIF_CHILDREN|TVIF_IMAGE | TVIF_SELECTEDIMAGE;
		item.pszText = szBuffer;
		item.cchTextMax = MAXTEXTLEN;
		::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
		str_tree=szBuffer;

		if(bImage)
		{			
			//xmlfile->SetString(tree_name, (str_parent+str_tree).c_str(), "" );
			sprintf(szBuffer, "%d", item.iImage);
			xmlfile->SetAttribute(tree_name, (str_parent+str_tree).c_str(),
				"iImage", szBuffer);
			sprintf(szBuffer, "%d", item.iSelectedImage);
			xmlfile->SetAttribute(tree_name, (str_parent+str_tree).c_str(),
				"iSelectedImage", szBuffer);
		}else
		{			
			xmlfile->SetString(tree_name, (str_parent+str_tree).c_str(), "" );
		}

		str_tree+="/";//add a separator		
		// Check whether we have child items.
		if (item.cChildren)
		{
			// Recursively traverse child items.
			HTREEITEM hItemFound, hItemChild;
			
			hItemChild = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM,
				TVGN_CHILD, (LPARAM)hItem);
			if(hItemChild!=NULL)
				hItemFound = SaveItems(xmlfile, tree_name, hItemChild, str_parent+str_tree, bImage);
			
			// Did we find it?
			if (hItemFound != NULL)
				return hItemFound;
		}
		
		// Go to next sibling item.
		hItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM,
			TVGN_NEXT, (LPARAM)hItem);
	}
	return hItem;
	
}

//delete a tree record form the specific xml file
void CPersistentTreeCtrl::DeleteTreeRecord(const char* filename, const char* tree_name)
{
	CXMLFile xmlfile;//(filename);
	xmlfile.load(filename);
	xmlfile.DeleteSetting( string(tree_name) .c_str(), "");
	xmlfile.save();
}

bool CPersistentTreeCtrl::Save(const char* filename, const char* tree_name, bool bImage)
{
	assert(!HasDuplicate() && "     提示:树控件每一层不应当有重复的项!     ");

	CXMLFile xmlfile(filename);
	SaveItems(&xmlfile, tree_name, NULL, "", bImage);
	xmlfile.save(filename);
	return true;
}

void CPersistentTreeCtrl::LoadItems(HTREEITEM hItem, MSXML2::IXMLDOMNodePtr& pNode, bool bImage)
{
	MSXML2::IXMLDOMNodePtr pTmpNode=NULL;
	MSXML2::IXMLDOMNodePtr pNdAttr=NULL;
	HTREEITEM hTmpItem=hItem;
	TV_INSERTSTRUCT TVIN;
	TVIN.hParent=hItem;
	TVIN.hInsertAfter=TVI_LAST;
	TV_ITEM item;
	char szBuffer[MAXTEXTLEN+1];
	szBuffer[0]=0;	

	while(pNode!=NULL)
	{	
		item.mask = TVIF_TEXT|TVIF_IMAGE | TVIF_SELECTEDIMAGE;
		item.pszText = szBuffer;
		item.cchTextMax = MAXTEXTLEN;
		if(bImage)
		{			
			pNdAttr=pNode->Getattributes()->getNamedItem("iImage");
			if(pNdAttr!=NULL)
			{
				strcpy(szBuffer, (const char*)pNdAttr->text );
				item.iImage=atoi(szBuffer);
			}
			pNdAttr=pNode->Getattributes()->getNamedItem("iSelectedImage");
			if(pNdAttr!=NULL)
			{		
				strcpy(szBuffer, (const char*)pNdAttr->text);
				item.iSelectedImage=atoi(szBuffer);	
			}
		}
		strcpy(szBuffer, (const char*)pNode->nodeName);
		TVIN.item=item;
		//hTmpItem=InsertItem(szBuffer, item.iImage, item.iSelectedImage, hItem);
		hTmpItem= (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&TVIN);
	
		// Check whether we have child items.
		if (pNode->hasChildNodes())
		{
			pTmpNode=pNode->GetfirstChild();
			LoadItems(hTmpItem, pTmpNode, bImage);//item.hItem
		}
	
		pNode=pNode->GetnextSibling();
	}
}

bool CPersistentTreeCtrl::Load(const char* filename, const char* tree_name, bool bImage)
{
	CXMLFile xmlfile(filename);
	MSXML2::IXMLDOMNodePtr PtrNode;
	xmlfile.GetNode(tree_name, PtrNode);
	
	if(PtrNode==NULL)
		return false;
	PtrNode=PtrNode->GetfirstChild();	

	if(PtrNode==NULL)
		return false;
	LoadItems(NULL, PtrNode, bImage);	
	//Expand(GetRootItem(), TVE_EXPAND);	

	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -