📄 tltree.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
TLTree.c - TreeList Tree linked list management routines
$Id: TLTree.c,v 1.7 2002/09/30 14:28:42 pbj Exp $
____________________________________________________________________________*/
#include "TLintern.h"
// _______________________________________________
//
// Remove the specified item from the tree linked list
static VOID
sRemoveItemFromTree (
TLWndData* pWD,
TLTreeItem* p)
{
if (p->prevItem)
p->prevItem->nextItem = p->nextItem;
else if (p->parentItem)
p->parentItem->childItem = p->nextItem;
else
pWD->rootItem = p->nextItem;
if (p->nextItem)
p->nextItem->prevItem = p->prevItem;
if (p->parentItem)
p->parentItem->cChildren--;
p->nextItem = NULL;
p->prevItem = NULL;
}
// _______________________________________________
//
// Reinsert Tree item into list
HTLITEM
TLReInsertTreeItem (
TLWndData* pWD,
LPTL_INSERTSTRUCT lpIns)
{
TLTreeItem* lpNew;
if (lpIns->item.hItem)
{
lpNew = (TLTreeItem*)(lpIns->item.hItem);
sRemoveItemFromTree (pWD, lpNew);
return TLInsertTreeItem (pWD, lpIns);
}
return NULL;
}
// _______________________________________________
//
// Select Tree item
static VOID
sSelectTreeItem (
TLWndData* pWD,
TLTreeItem* p)
{
p->state |= TLIS_SELECTED;
pWD->firstSelectItem = p;
(pWD->iNumberSelected)++;
TLInvalidateItem (pWD, p);
if (pWD->iNumberSelected > 1)
pWD->nmTreeList.flags = TLC_MULTIPLE;
else
pWD->nmTreeList.flags = 0;
pWD->nmTreeList.itemOld.hItem = NULL;
pWD->nmTreeList.itemNew.hItem = (HTLITEM)p;
pWD->nmTreeList.itemNew.state = p->state;
pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
SendMessage (pWD->hWndParent,
WM_NOTIFY, pWD->id, (LPARAM)&(pWD->nmTreeList));
}
// _______________________________________________
//
// Insert Tree item into list
HTLITEM
TLInsertTreeItem (
TLWndData* pWD,
LPTL_INSERTSTRUCT lpIns)
{
TLTreeItem* lpParent;
TLTreeItem* lpPrev;
TLTreeItem* lpNew;
TLListItem* pli;
int i;
// allocate new linked list structure if needed
if (!lpIns->item.hItem)
{
lpNew = TLAlloc (sizeof (TLTreeItem));
if (!lpNew)
return NULL;
lpNew->state = 0;
lpNew->childItem = NULL;
lpNew->listItem = NULL;
lpNew->cChildren = 0;
}
else
lpNew = (TLTreeItem*)(lpIns->item.hItem);
// get parent item
lpParent = (TLTreeItem*)lpIns->hParent;
lpNew->parentItem = lpParent;
// Insert item into list at appropriate spot
if (lpParent)
{
//not a root item
if (lpIns->hInsertAfter == TLI_FIRST)
{
lpNew->nextItem = lpParent->childItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpParent->childItem = lpNew;
lpNew->prevItem = NULL;
}
else if (lpIns->hInsertAfter == TLI_LAST)
{
lpPrev = lpParent->childItem;
if (lpPrev)
{
while (lpPrev->nextItem)
lpPrev = lpPrev->nextItem;
lpPrev->nextItem = lpNew;
lpNew->prevItem = lpPrev;
lpNew->nextItem = NULL;
}
else
{
lpParent->childItem = lpNew;
lpNew->nextItem = NULL;
lpNew->prevItem = NULL;
}
}
else if (lpIns->hInsertAfter == TLI_SORT)
{
lpPrev = lpParent->childItem;
if (!lpPrev)
{
lpParent->childItem = lpNew;
lpNew->nextItem = NULL;
lpNew->prevItem = NULL;
}
else
{
if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) >= 0)
{
lpNew->nextItem = lpParent->childItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpParent->childItem = lpNew;
lpNew->prevItem = NULL;
}
else
{
while (lpPrev->nextItem &&
(lstrcmp (lpPrev->nextItem->pszText,
lpIns->item.pszText) < 0))
{
lpPrev = lpPrev->nextItem;
}
lpNew->nextItem = lpPrev->nextItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpPrev->nextItem = lpNew;
lpNew->prevItem = lpPrev;
}
}
}
else if (lpIns->hInsertAfter == TLI_SORTREVERSE)
{
lpPrev = lpParent->childItem;
if (!lpPrev)
{
lpParent->childItem = lpNew;
lpNew->nextItem = NULL;
lpNew->prevItem = NULL;
}
else
{
if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) <= 0)
{
lpNew->nextItem = lpParent->childItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpParent->childItem = lpNew;
lpNew->prevItem = NULL;
}
else
{
while (lpPrev->nextItem &&
(lstrcmp (lpPrev->nextItem->pszText,
lpIns->item.pszText) > 0))
{
lpPrev = lpPrev->nextItem;
}
lpNew->nextItem = lpPrev->nextItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpPrev->nextItem = lpNew;
lpNew->prevItem = lpPrev;
}
}
}
else
{
lpPrev = (TLTreeItem*)lpIns->hInsertAfter;
if (lpPrev)
{
lpNew->prevItem = lpPrev;
lpNew->nextItem = lpPrev->nextItem;
lpPrev->nextItem = lpNew;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
}
}
lpParent->cChildren++;
}
// this is a root item
else
{
if (lpIns->hInsertAfter == TLI_FIRST)
{
lpNew->nextItem = pWD->rootItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpNew->prevItem = NULL;
pWD->rootItem = lpNew;
}
else if (lpIns->hInsertAfter == TLI_LAST)
{
lpPrev = pWD->rootItem;
if (lpPrev)
{
while (lpPrev->nextItem)
lpPrev = lpPrev->nextItem;
lpPrev->nextItem = lpNew;
lpNew->prevItem = lpPrev;
lpNew->nextItem = NULL;
}
else
{
pWD->rootItem = lpNew;
lpNew->nextItem = NULL;
lpNew->prevItem = NULL;
}
}
else if (lpIns->hInsertAfter == TLI_SORT)
{
lpPrev = pWD->rootItem;
if (!lpPrev)
{
pWD->rootItem = lpNew;
lpNew->nextItem = NULL;
lpNew->prevItem = NULL;
}
else
{
if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) >= 0)
{
lpNew->nextItem = pWD->rootItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
pWD->rootItem = lpNew;
lpNew->prevItem = NULL;
}
else
{
while (lpPrev->nextItem &&
(lstrcmp (lpPrev->nextItem->pszText,
lpIns->item.pszText) < 0))
{
lpPrev = lpPrev->nextItem;
}
lpNew->nextItem = lpPrev->nextItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpPrev->nextItem = lpNew;
lpNew->prevItem = lpPrev;
}
}
}
else if (lpIns->hInsertAfter == TLI_SORTREVERSE)
{
lpPrev = pWD->rootItem;
if (!lpPrev)
{
pWD->rootItem = lpNew;
lpNew->nextItem = NULL;
lpNew->prevItem = NULL;
}
else
{
if (lstrcmp (lpPrev->pszText, lpIns->item.pszText) <= 0)
{
lpNew->nextItem = pWD->rootItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
pWD->rootItem = lpNew;
lpNew->prevItem = NULL;
}
else
{
while (lpPrev->nextItem &&
(lstrcmp (lpPrev->nextItem->pszText,
lpIns->item.pszText) > 0))
{
lpPrev = lpPrev->nextItem;
}
lpNew->nextItem = lpPrev->nextItem;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
lpPrev->nextItem = lpNew;
lpNew->prevItem = lpPrev;
}
}
}
else
{
lpPrev = (TLTreeItem*)lpIns->hInsertAfter;
if (lpPrev)
{
lpNew->prevItem = lpPrev;
lpNew->nextItem = lpPrev->nextItem;
lpPrev->nextItem = lpNew;
if (lpNew->nextItem)
lpNew->nextItem->prevItem = lpNew;
}
}
}
// only do the following if this is a new item
if (!lpIns->item.hItem)
{
if (lpIns->item.mask & TLIF_TEXT)
{
lpNew->pszText = TLAlloc (lstrlen (lpIns->item.pszText) +1);
if (lpNew->pszText)
lstrcpy (lpNew->pszText, lpIns->item.pszText);
}
else
lpNew->pszText = NULL;
if (lpIns->item.mask & TLIF_IMAGE)
lpNew->iImage = lpIns->item.iImage;
else
lpNew->iImage = 0;
if (lpIns->item.mask & TLIF_PARAM)
lpNew->lParam = lpIns->item.lParam;
else
lpNew->lParam = 0;
if (lpIns->item.mask & TLIF_STATE)
{
lpNew->state &= ~lpIns->item.stateMask;
lpNew->state |= (lpIns->item.stateMask & lpIns->item.state);
if (lpNew->state & TLIS_FOCUSED)
{
if (pWD->focusItem)
pWD->focusItem->state &= ~TLIS_FOCUSED;
pWD->focusItem = lpNew;
}
if (lpNew->state & TLIS_SELECTED)
{
sSelectTreeItem (pWD, lpNew);
if (lpNew->state & TLIS_FOCUSED)
TLSelectAutoScroll (pWD, lpNew);
}
}
if (pWD->iNumberColumns > 1)
{
lpNew->listItem = TLAlloc (sizeof (TLListItem));
pli = lpNew->listItem;
for (i=2; i<pWD->iNumberColumns; i++)
{
pli->nextItem = TLAlloc (sizeof (TLListItem));
pli = pli->nextItem;
}
}
}
return (HTLITEM)lpNew;
}
// _______________________________________________
//
// Delete all children of item
BOOL
TLDeleteChildren (
TLWndData* pWD,
TL_TREEITEM* lpti)
{
TLTreeItem* p;
p = (TLTreeItem*) lpti->hItem;
if (!p)
return FALSE;
if (p->childItem)
{
TLDeleteTreeList (pWD, p->childItem);
p->childItem = NULL;
p->cChildren = 0;
return TRUE;
}
else
return FALSE;
}
// _______________________________________________
//
// Delete Tree item
BOOL
TLDeleteTreeItem (
TLWndData* pWD,
TL_TREEITEM* lpti)
{
TLTreeItem* p;
TLListItem* pli;
TLListItem* opli;
p = (TLTreeItem*)
lpti->hItem;
if (!p)
return FALSE;
sRemoveItemFromTree (pWD, p);
if (p->childItem)
TLDeleteTreeList (pWD, p->childItem);
if (pWD->focusItem == p)
pWD->focusItem = NULL;
if (pWD->firstSelectItem == p)
pWD->firstSelectItem = NULL;
pli = p->listItem;
while (pli)
{
TLFree (pli->pszText);
opli = pli;
pli = pli->nextItem;
TLFree (opli);
}
TLFree (p->pszText);
TLFree (p);
return TRUE;
}
// _______________________________________________
//
// Get Tree item information
BOOL
TLGetTreeItem (
TLWndData* pWD,
TL_TREEITEM* lpti)
{
TLTreeItem* p;
p = (TLTreeItem*)
lpti->hItem;
if (!p)
return FALSE;
if (lpti->mask & TLIF_TEXT)
{
if (lpti->cchTextMax > lstrlen (p->pszText))
lstrcpy (lpti->pszText, p->pszText);
else
{
lpti->pszText = NULL;
return FALSE;
}
}
if (lpti->mask & TLIF_IMAGE)
lpti->iImage = p->iImage;
if (lpti->mask & TLIF_PARAM)
lpti->lParam = p->lParam;
if (lpti->mask & TLIF_STATE)
lpti->state = p->state;
if (lpti->mask & TLIF_NEXTHANDLE)
lpti->hItem = (HTLITEM)p->nextItem;
else if (lpti->mask & TLIF_PREVHANDLE)
lpti->hItem = (HTLITEM)p->prevItem;
else if (lpti->mask & TLIF_PARENTHANDLE)
lpti->hItem = (HTLITEM)p->parentItem;
else if (lpti->mask & TLIF_CHILDHANDLE)
lpti->hItem = (HTLITEM)p->childItem;
return TRUE;
}
// _______________________________________________
//
// Set Tree item information
BOOL
TLSetTreeItem (
TLWndData* pWD,
TL_TREEITEM* lpti)
{
TLTreeItem* p;
p = (TLTreeItem*)
lpti->hItem;
if (!p)
return FALSE;
if (lpti->mask & TLIF_TEXT)
{
p->pszText = TLReAlloc (p->pszText, lstrlen (lpti->pszText) +1);
lstrcpy (p->pszText, lpti->pszText);
}
if (lpti->mask & TLIF_IMAGE)
p->iImage = lpti->iImage;
if (lpti->mask & TLIF_PARAM)
p->lParam = lpti->lParam;
if (lpti->mask & TLIF_STATE)
{
p->state &= ~(lpti->stateMask);
p->state |= (lpti->state & lpti->stateMask);
if (p->state & TLIS_FOCUSED)
{
if (pWD->focusItem != p)
{
if (pWD->focusItem)
pWD->focusItem->state &= ~TLIS_FOCUSED;
pWD->focusItem = p;
}
}
if (p->state & TLIS_SELECTED)
sSelectTreeItem (pWD, p);
}
TLInvalidateItem (pWD, p);
return TRUE;
}
// _______________________________________________
//
// Deselect Tree
BOOL
TLDeselectTree (
TLWndData* pWD,
TLTreeItem* p,
TLTreeItem* pExcept)
{
BOOL bDeselected = FALSE;
while (p)
{
if (p->childItem)
bDeselected = TLDeselectTree (pWD, p->childItem, pExcept);
if (p != pExcept)
{
if (p->state & TLIS_SELECTED)
{
p->state &= ~TLIS_SELECTED;
pWD->iNumberSelected--;
TLInvalidateItem (pWD, p);
bDeselected = TRUE;
}
if (p->state & TLIS_FOCUSED)
{
p->state &= ~TLIS_FOCUSED;
pWD->nmTreeList.flags = 0;
pWD->nmTreeList.itemOld.hItem = NULL;
pWD->nmTreeList.itemNew.hItem = NULL;
pWD->nmTreeList.itemNew.state = 0;
pWD->nmTreeList.hdr.code = TLN_SELCHANGED;
SendMessage (pWD->hWndParent,
WM_NOTIFY, pWD->id, (LPARAM)&(pWD->nmTreeList));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -