?? persistenttreectrl.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 + -