26#define STVN_ROOT ((HSTREENODE)(ULONG_PTR)0xFFFF000000000000)
27#define STVN_FIRST ((HSTREENODE)(ULONG_PTR)0xFFFF000000000001)
28#define STVN_LAST ((HSTREENODE)(ULONG_PTR)0xFFFF000000000002)
29#define STVL_ROOT ((PSTREELINK)(ULONG_PTR)0xFFFF000000000000)
31#define STVN_ROOT ((HSTREENODE)(ULONG_PTR)0xFFFF0000)
32#define STVN_FIRST ((HSTREENODE)(ULONG_PTR)0xFFFF0001)
33#define STVN_LAST ((HSTREENODE)(ULONG_PTR)0xFFFF0002)
34#define STVL_ROOT ((PSTREELINK)(ULONG_PTR)0xFFFF0000)
39#define STVI_ROOT ((HSTREEITEM)0xFFFF000000000000)
40#define STVI_FIRST ((HSTREEITEM)0xFFFF000000000001)
41#define STVI_LAST ((HSTREEITEM)0xFFFF000000000002)
43#define STVI_ROOT ((HSTREEITEM)0xFFFF0000)
44#define STVI_FIRST ((HSTREEITEM)0xFFFF0001)
45#define STVI_LAST ((HSTREEITEM)0xFFFF0002)
63 typedef struct _STREENODE
65 struct _STREENODE *hParent;
66 struct _STREENODE *hChildFirst;
67 struct _STREENODE *hChildLast;
68 struct _STREENODE *hPrevSibling;
69 struct _STREENODE *hNextSibling;
71 } STREENODE, *HSTREENODE;
79 typedef struct _STREELINK
82 HSTREENODE hChildFirst;
83 HSTREENODE hChildLast;
84 HSTREENODE hPrevSibling;
85 HSTREENODE hNextSibling;
86 } STREELINK, *PSTREELINK;
97 typedef BOOL (*CBTRAVERSING)(T *, LPARAM);
102 virtual void OnDataFree(T &data) = 0;
144 PSTREELINK pLink = (PSTREELINK)hItem;
145 SASSERT(pLink && pLink != STVL_ROOT);
146 return (HSTREEITEM)pLink->hNextSibling;
156 PSTREELINK pLink = (PSTREELINK)hItem;
157 SASSERT(pLink && pLink != STVL_ROOT);
158 return (HSTREEITEM)pLink->hPrevSibling;
168 PSTREELINK pLink = (PSTREELINK)hItem;
169 SASSERT(pLink && pLink != STVL_ROOT);
170 return (HSTREEITEM)pLink->hParent;
198 HSTREEITEM hParent = hItem;
214 HSTREENODE hsNode = (HSTREENODE)hItem;
226 return (HSTREEITEM)hsNode->hChildFirst;
228 return (HSTREEITEM)hsNode->hChildLast;
255 HSTREENODE hsNode = (HSTREENODE)hItem;
264 STREENODE nodeCopy = *hsNode;
269 if (nodeCopy.hPrevSibling)
270 nodeCopy.hPrevSibling->hNextSibling = nodeCopy.hNextSibling;
271 else if (nodeCopy.hParent)
272 nodeCopy.hParent->hChildFirst = nodeCopy.hNextSibling;
273 if (nodeCopy.hNextSibling)
274 nodeCopy.hNextSibling->hPrevSibling = nodeCopy.hPrevSibling;
275 else if (nodeCopy.hParent)
276 nodeCopy.hParent->hChildLast = nodeCopy.hPrevSibling;
310 HSTREENODE hsNode = (HSTREENODE)hItem;
323 HSTREENODE hsNode = (HSTREENODE)hItem;
336 HSTREENODE hsNode = (HSTREENODE)hItem;
338 return &hsNode->data;
350 HSTREENODE hParentNode = (HSTREENODE)hParent;
351 HSTREENODE hInsertAfterNode = (HSTREENODE)hInsertAfter;
354 SASSERT(hInsertAfter);
357 if (hInsertAfterNode->hParent != hParentNode)
359 if (hInsertAfterNode->hNextSibling == NULL)
363 HSTREENODE hInserted =
new STREENODE;
364 hInserted->data = data;
365 hInserted->hParent = hParentNode;
366 hInserted->hChildFirst = NULL;
367 hInserted->hChildLast = NULL;
371 hInserted->hPrevSibling = NULL;
372 if (hParentNode == NULL)
383 hInserted->hNextSibling = hParentNode->hChildFirst;
384 if (hInserted->hNextSibling)
386 hInserted->hNextSibling->hPrevSibling = hInserted;
387 hParentNode->hChildFirst = hInserted;
391 hParentNode->hChildLast = hParentNode->hChildFirst = hInserted;
397 hInserted->hNextSibling = NULL;
398 if (hParentNode == NULL)
409 hInserted->hPrevSibling = hParentNode->hChildLast;
410 if (hParentNode->hChildLast)
412 hInserted->hPrevSibling->hNextSibling = hInserted;
413 hParentNode->hChildLast = hInserted;
417 hParentNode->hChildLast = hParentNode->hChildFirst = hInserted;
423 HSTREENODE hNextSibling = hInsertAfterNode->hNextSibling;
424 hInserted->hPrevSibling = hInsertAfterNode;
425 hInserted->hNextSibling = hNextSibling;
426 hNextSibling->hPrevSibling = hInsertAfterNode->hNextSibling = hInserted;
428 return (HSTREEITEM)hInserted;
443 if (funTraversing(
GetItemPt(hItem), lParam))
458 if (funTraversing(
GetItemPt(hChild), lParam))
483 if (funTraversing(
GetItemPt(hItem), lParam))
489 if (funTraversing(
GetItemPt(hNext), lParam))
546 HSTREEITEM hParent = hItem;
582 HSTREEITEM hParent = hItem;
604 void SortChildren(HSTREEITEM hItem,
int(__cdecl *funSort)(
void *,
const void *,
const void *),
void *pCtx)
609 HSTREEITEM *pChilds =
new HSTREEITEM[nChilds];
612 for (
int i = 1; i < nChilds; i++)
618 qsort_s(pChilds, nChilds,
sizeof(HSTREEITEM), funSort, pCtx);
620 for (
int i = 0; i < nChilds - 1; i++)
622 HSTREENODE node = (HSTREENODE)pChilds[i];
623 node->hNextSibling = (HSTREENODE)pChilds[i + 1];
625 for (
int i = 1; i < nChilds; i++)
627 HSTREENODE node = (HSTREENODE)pChilds[i];
628 node->hPrevSibling = (HSTREENODE)pChilds[i - 1];
630 HSTREENODE node = (HSTREENODE)pChilds[0];
631 node->hPrevSibling = NULL;
632 node = (HSTREENODE)pChilds[nChilds - 1];
633 node->hNextSibling = NULL;
636 HSTREENODE parent = (HSTREENODE)hItem;
637 parent->hChildFirst = (HSTREENODE)pChilds[0];
638 parent->hChildLast = (HSTREENODE)pChilds[nChilds - 1];
651 HSTREENODE node = (HSTREENODE)hChild;
652 if (node->hChildFirst && node->hChildLast && node->hChildFirst != node->hChildLast)
682 void FreeNode(HSTREENODE hsNode)
685 HSTREENODE hSibling = (HSTREENODE)
GetChildItem((HSTREEITEM)hsNode);
688 HSTREENODE hNextSibling = hSibling->hNextSibling;
690 hSibling = hNextSibling;
static T GetItem(HSTREEITEM hItem)
Get the item data.
virtual void OnNodeFree(T &data)
Virtual function to handle the freeing of node data.
HSTREEITEM GetChildItem(HSTREEITEM hItem, BOOL bFirst=TRUE) const
Get the child item.
HSTREEITEM TraversingRecursion(HSTREEITEM hItem, CBTRAVERSING funTraversing, LPARAM lParam)
Traverse the tree recursively.
static HSTREEITEM GetParentItem(HSTREEITEM hItem)
Get the parent item.
void SetDataFreer(IDataFreer *cbFree)
Set the data freer callback.
HSTREEITEM GetNextItem(HSTREEITEM hItem) const
Get the next item in the tree.
virtual ~CSTree()
Destructor.
virtual void DeleteItem(HSTREEITEM hItem)
Delete an item.
int GetChildrenCount(HSTREEITEM hItem) const
Get the number of children.
HSTREEITEM GetNextItem(HSTREEITEM hItem, int &nLevel) const
Get the next item in the tree with level relationship.
static int GetItemLevel(HSTREEITEM hItem)
Get the level of the item.
HSTREEITEM InsertItem(const T &data, HSTREEITEM hParent=((HSTREEITEM) 0xFFFF0000), HSTREEITEM hInsertAfter=((HSTREEITEM) 0xFFFF0002))
Insert a new item.
void DeleteAllItems()
Delete all items in the tree.
HSTREEITEM TraversingSequence(HSTREEITEM hItem, CBTRAVERSING funTraversing, LPARAM lParam)
Traverse the tree in sequence.
static HSTREEITEM GetNextSiblingItem(HSTREEITEM hItem)
Get the next sibling item.
BOOL DeleteItemEx(HSTREEITEM hItem)
Delete an item and its branch.
static T * GetItemPt(HSTREEITEM hItem)
Get the item data pointer.
static T & GetItemRef(HSTREEITEM hItem)
Get the item data reference.
static HSTREEITEM GetPrevSiblingItem(HSTREEITEM hItem)
Get the previous sibling item.
static HSTREEITEM GetRootItem(HSTREEITEM hItem)
Get the root item of the specified node.
void SortChildren(HSTREEITEM hItem, int(__cdecl *funSort)(void *, const void *, const void *), void *pCtx)
Sort the children of a node.
int GetDesendants(HSTREEITEM hItem)
Get the number of descendants of a node.
HSTREEITEM GetRootItem(BOOL bFirst=TRUE)
Get the root item.