You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2236 lines
63 KiB
2236 lines
63 KiB
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1996-2002 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// TreeItem.cpp
|
|
//
|
|
// Abstract:
|
|
// Implementation of the CTreeItem class.
|
|
//
|
|
// Author:
|
|
// David Potter (davidp) May 3, 1996
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "ConstDef.h"
|
|
#include "TreeItem.h"
|
|
#include "TreeItem.inl"
|
|
#include "TreeView.h"
|
|
#include "ListView.h"
|
|
#include "ClusDoc.h"
|
|
#include "SplitFrm.h"
|
|
#include "TraceTag.h"
|
|
#include "ExcOper.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Global Variables
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef _DEBUG
|
|
CTraceTag g_tagTreeItemUpdate(_T("UI"), _T("TREE ITEM UPDATE"), 0);
|
|
CTraceTag g_tagTreeItemSelect(_T("UI"), _T("TREE ITEM SELECT"), 0);
|
|
CTraceTag g_tagTreeItemCreate(_T("Create"), _T("TREE ITEM CREATE"), 0);
|
|
CTraceTag g_tagTreeItemDelete(_T("Delete"), _T("TREE ITEM DELETE"), 0);
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTreeItemList
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItemList::PtiFromPci
|
|
//
|
|
// Routine Description:
|
|
// Find a tree item in the list by its cluster item.
|
|
//
|
|
// Arguments:
|
|
// pci [IN] Cluster item to search for.
|
|
// ppos [OUT] Position of the item in the list.
|
|
//
|
|
// Return Value:
|
|
// pti Tree item corresponding to the cluster item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItemList::PtiFromPci(
|
|
IN const CClusterItem * pci,
|
|
OUT POSITION * ppos // = NULL
|
|
) const
|
|
{
|
|
POSITION posPti;
|
|
POSITION posCurPti;
|
|
CTreeItem * pti = NULL;
|
|
|
|
posPti = GetHeadPosition();
|
|
while (posPti != NULL)
|
|
{
|
|
posCurPti = posPti;
|
|
pti = GetNext(posPti);
|
|
ASSERT_VALID(pti);
|
|
|
|
if (pti->Pci() == pci)
|
|
{
|
|
if (ppos != NULL)
|
|
*ppos = posCurPti;
|
|
break;
|
|
} // if: found a match
|
|
|
|
pti = NULL;
|
|
} // while: more resources in the list
|
|
|
|
return pti;
|
|
|
|
} //*** CTreeItemList::PtiFromPci()
|
|
|
|
|
|
//***************************************************************************
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTreeItem
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
IMPLEMENT_DYNCREATE(CTreeItem, CBaseCmdTarget)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message Maps
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BEGIN_MESSAGE_MAP(CTreeItem, CBaseCmdTarget)
|
|
//{{AFX_MSG_MAP(CTreeItem)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::CTreeItem
|
|
//
|
|
// Routine Description:
|
|
// Default constructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem::CTreeItem(void)
|
|
{
|
|
m_ptiParent = NULL;
|
|
m_pci = NULL;
|
|
m_bWeOwnPci = FALSE;
|
|
|
|
} //*** CTreeItem::CTreeItem()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::CTreeItem
|
|
//
|
|
// Routine Description:
|
|
// Constructor.
|
|
//
|
|
// Arguments:
|
|
// ptiParent [IN OUT] Parent item for this item.
|
|
// pci [IN OUT] Cluster item represented by this tree item.
|
|
// bTakeOwnership [IN] TRUE = delete pci when this object is destroyed.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem::CTreeItem(
|
|
IN OUT CTreeItem * ptiParent,
|
|
IN OUT CClusterItem * pci,
|
|
IN BOOL bTakeOwnership // = FALSE
|
|
)
|
|
{
|
|
ASSERT_VALID(pci);
|
|
|
|
m_ptiParent = ptiParent;
|
|
m_pci = pci;
|
|
m_bWeOwnPci = bTakeOwnership;
|
|
|
|
m_pci->AddRef();
|
|
|
|
// Set the column section name. If there is a parent, append our name
|
|
// onto the parent's section name.
|
|
try
|
|
{
|
|
if (PtiParent() == NULL)
|
|
m_strProfileSection.Format(
|
|
REGPARAM_CONNECTIONS _T("\\%s\\%s"),
|
|
Pci()->Pdoc()->StrNode(),
|
|
Pci()->StrName()
|
|
);
|
|
else
|
|
m_strProfileSection.Format(
|
|
_T("%s\\%s"),
|
|
PtiParent()->StrProfileSection(),
|
|
Pci()->StrName()
|
|
);
|
|
} // try
|
|
catch (CException * pe)
|
|
{
|
|
// If an error occurs constructing the section name, just ignore it.
|
|
pe->Delete();
|
|
} // catch: CException
|
|
|
|
Trace(g_tagTreeItemCreate, _T("CTreeItem() - Creating '%s', parent = '%s', owned = %d"), pci->StrName(), (ptiParent ? ptiParent->Pci()->StrName() : _T("<None>")), bTakeOwnership);
|
|
|
|
} //*** CTreeItem::CTreeItem(pci)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::Init
|
|
//
|
|
// Routine Description:
|
|
// Initialize the tree item.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::Init(void)
|
|
{
|
|
} //*** CTreeItem::Init()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::~CTreeItem
|
|
//
|
|
// Routine Description:
|
|
// Destructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem::~CTreeItem(void)
|
|
{
|
|
#ifdef _DEBUG
|
|
TCHAR szName[1024];
|
|
HRESULT hr;
|
|
|
|
if (Pci() != NULL)
|
|
{
|
|
hr = StringCchCopyN( szName, RTL_NUMBER_OF( szName ), Pci()->StrName(), Pci()->StrName().GetLength() );
|
|
ASSERT( SUCCEEDED( hr ) );
|
|
}
|
|
else
|
|
{
|
|
hr = StringCchCopy( szName, RTL_NUMBER_OF( szName ), _T("<Unknown>") );
|
|
ASSERT( SUCCEEDED( hr ) );
|
|
}
|
|
|
|
Trace(g_tagTreeItemDelete, _T("~CTreeItem() - Deleting tree item '%s'"), szName);
|
|
#endif
|
|
|
|
// Cleanup this object.
|
|
Cleanup();
|
|
|
|
Trace(g_tagTreeItemDelete, _T("~CTreeItem() - Done deleting tree item '%s'"), szName);
|
|
|
|
} //*** CTreeItem::~CTreeItem()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::Delete
|
|
//
|
|
// Routine Description:
|
|
// Delete the item. If the item still has references, add it to the
|
|
// document's pending delete list.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
// Exceptions Thrown:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::Delete(void)
|
|
{
|
|
// Add a reference so that we don't delete ourselves while
|
|
// still doing cleanup.
|
|
AddRef();
|
|
|
|
// Cleanup this object.
|
|
Cleanup();
|
|
|
|
// If there are still references to this object, add it to the delete
|
|
// pending list. Check for greater than 1 because we added a reference
|
|
// at the beginning of this method.
|
|
// if (NReferenceCount() > 1)
|
|
// {
|
|
// ASSERT(Pdoc()->LpciToBeDeleted().Find(this) == NULL);
|
|
// Pdoc()->LpciToBeDeleted().AddTail(this);
|
|
// } // if: object still has references to it
|
|
|
|
// Release the reference we added at the beginning. This will
|
|
// cause the object to be deleted if we were the last reference.
|
|
Release();
|
|
|
|
} //*** CTreeItem::Delete()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::Cleanup
|
|
//
|
|
// Routine Description:
|
|
// Cleanup the item.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
// Exceptions Thrown:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::Cleanup(void)
|
|
{
|
|
// Delete our children first.
|
|
// NOTE: List items MUST be deleted first since tree items delete
|
|
// owned cluster items.
|
|
DeleteAllItemData(m_lpliChildren);
|
|
DeleteAllItemData(m_lptiChildren);
|
|
m_lpliChildren.RemoveAll();
|
|
m_lptiChildren.RemoveAll();
|
|
|
|
// Remove ourself from all views.
|
|
RemoveFromAllLists();
|
|
|
|
// Delete all other lists.
|
|
DeleteAllItemData(m_lpcoli);
|
|
DeleteAllItemData(m_lptic);
|
|
m_lpcoli.RemoveAll();
|
|
m_lptic.RemoveAll();
|
|
|
|
// If we own the cluster item, delete it.
|
|
if (m_bWeOwnPci)
|
|
{
|
|
#ifdef _DEBUG
|
|
TCHAR szName[1024];
|
|
HRESULT hr;
|
|
|
|
if (Pci() != NULL)
|
|
{
|
|
hr = StringCchCopyN( szName, RTL_NUMBER_OF( szName ), Pci()->StrName(), Pci()->StrName().GetLength() );
|
|
ASSERT( SUCCEEDED( hr ) );
|
|
}
|
|
else
|
|
{
|
|
hr = StringCchCopy( szName, RTL_NUMBER_OF( szName ), _T("<Unknown>") );
|
|
ASSERT( SUCCEEDED( hr ) );
|
|
}
|
|
Trace(g_tagTreeItemDelete, _T("Cleanup --> Deleting cluster item '%s'"), szName);
|
|
#endif
|
|
delete m_pci;
|
|
} // if: we own the cluster item
|
|
else if (m_pci != NULL)
|
|
m_pci->Release();
|
|
m_pci = NULL;
|
|
|
|
} //*** CTreeItem::Cleanup()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::StrProfileSection
|
|
//
|
|
// Routine Description:
|
|
// Return the profile section name for this item.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// CString Reference to profile section string.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
const CString & CTreeItem::StrProfileSection(void)
|
|
{
|
|
ASSERT_VALID(Pci());
|
|
|
|
if (Pci() != NULL)
|
|
{
|
|
// Set the column section name. If there is a parent, append our name
|
|
// onto the parent's section name.
|
|
try
|
|
{
|
|
if (PtiParent() == NULL)
|
|
{
|
|
ASSERT_VALID(Pci()->Pdoc());
|
|
m_strProfileSection.Format(
|
|
REGPARAM_CONNECTIONS _T("\\%s\\%s"),
|
|
Pci()->Pdoc()->StrNode(),
|
|
Pci()->StrName()
|
|
);
|
|
} // if: item has no parent
|
|
else
|
|
{
|
|
m_strProfileSection.Format(
|
|
_T("%s\\%s"),
|
|
PtiParent()->StrProfileSection(),
|
|
Pci()->StrName()
|
|
);
|
|
} // else: item has a parent
|
|
} // try
|
|
catch (CException * pe)
|
|
{
|
|
// If an error occurs constructing the section name, just ignore it.
|
|
pe->Delete();
|
|
} // catch: CException
|
|
} // if: valid cluster item and document
|
|
|
|
return m_strProfileSection;
|
|
|
|
} //*** CTreeItem::StrProfileSection()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PtiAddChildBefore
|
|
//
|
|
// Routine Description:
|
|
// Add a child to the item's list of children following the specified
|
|
// item. Also creates an entry in the list of children list items.
|
|
//
|
|
// Arguments:
|
|
// pciOld [IN] Cluster item to follow the new tree item.
|
|
// pciNew [IN OUT] Cluster item represented by the new tree item.
|
|
// bTakeOwnership [IN] TRUE = delete pci when done, FALSE = don't delete.
|
|
//
|
|
// Return Value:
|
|
// ptiChild The new child item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItem::PtiAddChildBefore(
|
|
IN const CClusterItem * pciOld,
|
|
OUT CClusterItem * pciNew,
|
|
IN BOOL bTakeOwnership // = FALSE
|
|
)
|
|
{
|
|
CTreeItem * ptiOldChild;
|
|
CTreeItem * ptiNewChild;
|
|
CListItem * pliChild;
|
|
POSITION posOld;
|
|
|
|
// If no old was specified, add to the tail.
|
|
if (pciOld == NULL)
|
|
return PtiAddChild(pciNew, bTakeOwnership);
|
|
|
|
// Find the old item.
|
|
ptiOldChild = LptiChildren().PtiFromPci(pciOld, &posOld);
|
|
ASSERT_VALID(ptiOldChild);
|
|
|
|
// Create a child tree item.
|
|
ptiNewChild = new CTreeItem(this, pciNew, bTakeOwnership);
|
|
if (ptiNewChild == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
} // if: error allocating the tree item
|
|
ASSERT_VALID(ptiNewChild);
|
|
ptiNewChild->Init();
|
|
|
|
// Add the item before the specified item.
|
|
VERIFY((m_lptiChildren.InsertBefore(posOld, ptiNewChild)) != NULL);
|
|
|
|
// Add it to the back of the cluster item's list.
|
|
pciNew->AddTreeItem(ptiNewChild);
|
|
|
|
// Create a list item.
|
|
pliChild = PliAddChild(pciNew);
|
|
ASSERT_VALID(pliChild);
|
|
|
|
// Insert the new tree item in all tree controls.
|
|
InsertChildInAllTrees(ptiNewChild);
|
|
|
|
return ptiNewChild;
|
|
|
|
} //*** CTreeItem::PtiAddChildBefore()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::InsertChildInAllTrees
|
|
//
|
|
// Routine Description:
|
|
// Insert a child item in all tree controls. The child item must have
|
|
// already been inserted in the list of child tree items.
|
|
//
|
|
// Arguments:
|
|
// ptiNewChild [IN OUT] Tree item to be inserted.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::InsertChildInAllTrees(IN OUT CTreeItem * ptiNewChild)
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * pticParent;
|
|
POSITION posPrevChild;
|
|
HTREEITEM htiPrevChild;
|
|
CTreeItemContext * pticPrevChild;
|
|
CTreeItem * ptiPrevChild;
|
|
CTreeItemContext * pticNewChild;
|
|
CTreeCtrl * ptc;
|
|
CString strName;
|
|
|
|
ASSERT_VALID(ptiNewChild);
|
|
|
|
// Find the position of the child being inserted. Then get the address
|
|
// of the child before the one being inserted. This requires two calls
|
|
// to GetPrev.
|
|
VERIFY((posPrevChild = LptiChildren().Find(ptiNewChild)) != NULL); // Get new child pos.
|
|
VERIFY((ptiPrevChild = LptiChildren().GetPrev(posPrevChild)) != NULL); // Get pointer to new child.
|
|
if (posPrevChild == NULL) // If this is the first child,
|
|
{
|
|
htiPrevChild = TVI_FIRST; // set the hti to that value.
|
|
ptiPrevChild = NULL;
|
|
} // if: new child is not the first child
|
|
else
|
|
{
|
|
htiPrevChild = NULL;
|
|
ptiPrevChild = LptiChildren().GetPrev(posPrevChild); // Get pointer to prev child.
|
|
ASSERT_VALID(ptiPrevChild);
|
|
} // else: new child is the first child
|
|
|
|
// Loop through all the tree item contexts and add this item
|
|
// to the tree controls.
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
// Get the parent's tree item context.
|
|
pticParent = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(pticParent);
|
|
|
|
// Get the child's tree item context.
|
|
if (ptiPrevChild != NULL)
|
|
{
|
|
pticPrevChild = ptiPrevChild->PticFromFrame(pticParent->m_pframe);
|
|
ASSERT_VALID(pticPrevChild);
|
|
htiPrevChild = pticPrevChild->m_hti;
|
|
} // if: not inserting at beginning of list
|
|
|
|
// Allocate a new tree item context.
|
|
pticNewChild = new CTreeItemContext(pticParent->m_pframe, ptiNewChild, NULL, FALSE /*bExpanded*/);
|
|
if (pticNewChild == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
} // if: error allocating the tree item context
|
|
ASSERT_VALID(pticNewChild);
|
|
pticNewChild->Init();
|
|
ptiNewChild->m_lptic.AddTail(pticNewChild);
|
|
|
|
// Get the name to show in the tree.
|
|
ptiNewChild->Pci()->GetTreeName(strName);
|
|
|
|
// Insert the item in the tree.
|
|
ASSERT_VALID(pticParent->m_pframe);
|
|
ASSERT_VALID(pticParent->m_pframe->PviewTree());
|
|
ptc = &pticParent->m_pframe->PviewTree()->GetTreeCtrl();
|
|
VERIFY((pticNewChild->m_hti = ptc->InsertItem(strName, pticParent->m_hti, htiPrevChild)) != NULL);
|
|
VERIFY(ptc->SetItemData(pticNewChild->m_hti, (DWORD_PTR) ptiNewChild));
|
|
} // while: more tree item contexts in the list
|
|
|
|
} //*** CTreeItem::InsertChildInAllTrees()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PtiAddChild(CClusterItem*)
|
|
//
|
|
// Routine Description:
|
|
// Add a child to the item's list of children. Also creates an entry
|
|
// in the list of children list items.
|
|
//
|
|
// Arguments:
|
|
// pci [IN OUT] Cluster item represented by the new tree item.
|
|
// bTakeOwnership [IN] TRUE = delete pci when done, FALSE = don't delete.
|
|
//
|
|
// Return Value:
|
|
// ptiChild The new child item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItem::PtiAddChild(
|
|
IN OUT CClusterItem * pci,
|
|
IN BOOL bTakeOwnership // = FALSE
|
|
)
|
|
{
|
|
CTreeItem * ptiChild;
|
|
CListItem * pliChild;
|
|
|
|
ASSERT_VALID(pci);
|
|
|
|
// Create a child tree item.
|
|
ptiChild = new CTreeItem(this, pci, bTakeOwnership);
|
|
if (ptiChild == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
goto Cleanup;
|
|
} // if: error allocating the child tree item
|
|
ASSERT_VALID(ptiChild);
|
|
ptiChild->Init();
|
|
|
|
// Add the item to the list of child tree items.
|
|
m_lptiChildren.AddTail(ptiChild);
|
|
|
|
// Add ourselves to the back of the cluster item's list.
|
|
pci->AddTreeItem(ptiChild);
|
|
|
|
// Create a list item.
|
|
pliChild = PliAddChild(pci);
|
|
ASSERT_VALID(pliChild);
|
|
|
|
// Insert the new tree item in all tree controls.
|
|
InsertChildInAllTrees(ptiChild);
|
|
|
|
Cleanup:
|
|
|
|
return ptiChild;
|
|
|
|
} //*** CTreeItem::PtiAddChild(CClusterItem*)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PtiAddChild(CString&)
|
|
//
|
|
// Routine Description:
|
|
// Add a child to the item's list of children. Also creates an entry
|
|
// in the list of children list items.
|
|
//
|
|
// Arguments:
|
|
// rstrName [IN] String for the name of the item.
|
|
//
|
|
// Return Value:
|
|
// ptiChild The new child item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItem::PtiAddChild(IN const CString & rstrName)
|
|
{
|
|
CClusterItem * pci;
|
|
CTreeItem * ptiChild;
|
|
|
|
// Create the cluster item.
|
|
pci = new CClusterItem(&rstrName);
|
|
if (pci == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
} // if: error allocating the cluster item
|
|
ASSERT_VALID(pci);
|
|
|
|
// Add the cluster item to our list of children.
|
|
ptiChild = PtiAddChild(pci, TRUE /*bTakeOwnership*/);
|
|
ASSERT_VALID(ptiChild);
|
|
|
|
return ptiChild;
|
|
|
|
} //*** CTreeItem::PtiAddChild(CString&)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PtiAddChild(IDS)
|
|
//
|
|
// Routine Description:
|
|
// Add a child to the item's list of children. Also creates an entry
|
|
// in the list of children list items.
|
|
//
|
|
// Arguments:
|
|
// idsName [IN] String resource ID for the name of the item.
|
|
//
|
|
// Return Value:
|
|
// ptiChild The new child item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItem::PtiAddChild(IN IDS idsName)
|
|
{
|
|
CString strName;
|
|
|
|
ASSERT(idsName != 0);
|
|
|
|
strName.LoadString(idsName);
|
|
return PtiAddChild(strName);
|
|
|
|
} //*** CTreeItem::PtiAddChild(IDS)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PliAddChild
|
|
//
|
|
// Routine Description:
|
|
// Add a child to the item's list of children list items.
|
|
//
|
|
// Arguments:
|
|
// pci [IN OUT] Cluster item represented by the list item.
|
|
//
|
|
// Return Value:
|
|
// pliChild The new child item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CListItem * CTreeItem::PliAddChild(IN OUT CClusterItem * pci)
|
|
{
|
|
CListItem * pliChild;
|
|
|
|
ASSERT_VALID(pci);
|
|
|
|
// Create a list item.
|
|
pliChild = new CListItem(pci, this);
|
|
if (pliChild == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
} // if: error allocating the list item
|
|
ASSERT_VALID(pliChild);
|
|
|
|
// Add the list item to the list of child list items.
|
|
m_lpliChildren.AddTail(pliChild);
|
|
|
|
// Add the list item to the cluster item's list.
|
|
pci->AddListItem(pliChild);
|
|
|
|
// Add the list item to any list views.
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * ptic;
|
|
int ili;
|
|
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
|
|
if (ptic->m_pframe->PviewTree()->HtiSelected() == ptic->m_hti)
|
|
{
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
VERIFY((ili = pliChild->IliInsertInList(ptic->m_pframe->PviewList())) != -1);
|
|
} // if: currently showing children in list view
|
|
} // while: item is showing in more views
|
|
} // Add the list item to any list views
|
|
|
|
return pliChild;
|
|
|
|
} //*** CTreeItem::PliAddChild()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::RemoveItem
|
|
//
|
|
// Routine Description:
|
|
// Remove the item from the tree.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::RemoveItem(void)
|
|
{
|
|
ASSERT_VALID(PtiParent());
|
|
PtiParent()->RemoveChild(Pci());
|
|
|
|
} //*** CTreeItem::RemoveItem()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::RemoveChild
|
|
//
|
|
// Routine Description:
|
|
// Remove a child from the item's list of children list items.
|
|
//
|
|
// Arguments:
|
|
// pci [IN OUT] Cluster item represented by the list item.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::RemoveChild(IN OUT CClusterItem * pci)
|
|
{
|
|
ASSERT_VALID(pci);
|
|
|
|
// Remove the item from the list of list items.
|
|
{
|
|
CListItem * pliChild;
|
|
POSITION posPli;
|
|
|
|
pliChild = PliChildFromPci(pci);
|
|
if (pliChild != NULL)
|
|
{
|
|
pliChild->RemoveFromAllLists();
|
|
posPli = LpliChildren().Find(pliChild);
|
|
ASSERT(posPli != NULL);
|
|
m_lpliChildren.RemoveAt(posPli);
|
|
Trace(g_tagTreeItemDelete, _T("RemoveChild() - Deleting child list item '%s' from '%s' - %d left"), pliChild->Pci()->StrName(), Pci()->StrName(), LpliChildren().GetCount());
|
|
delete pliChild;
|
|
} // if: child lives in the list
|
|
|
|
} // Remove the item from the list of list items
|
|
|
|
// Remove the item from the list of tree items.
|
|
{
|
|
CTreeItem * ptiChild;
|
|
CTreeItem * ptiChildChild;
|
|
POSITION posPti;
|
|
ULONG nReferenceCount;
|
|
|
|
ptiChild = PtiChildFromPci(pci);
|
|
if (ptiChild != NULL)
|
|
{
|
|
// Remove the children of this child.
|
|
{
|
|
posPti = ptiChild->LptiChildren().GetHeadPosition();
|
|
while (posPti != NULL)
|
|
{
|
|
ptiChildChild = ptiChild->LptiChildren().GetNext(posPti);
|
|
ASSERT_VALID(ptiChildChild);
|
|
ptiChildChild->RemoveItem();
|
|
} // while: more items in the list
|
|
} // Remove the children of this child
|
|
|
|
posPti = LptiChildren().Find(ptiChild);
|
|
ASSERT(posPti != NULL);
|
|
nReferenceCount = ptiChild->NReferenceCount();
|
|
m_lptiChildren.RemoveAt(posPti);
|
|
Trace(g_tagTreeItemDelete, _T("RemoveChild() - Deleting child tree item '%s' from '%s' - %d left"), ptiChild->Pci()->StrName(), Pci()->StrName(), LptiChildren().GetCount());
|
|
if (nReferenceCount > 1)
|
|
{
|
|
ptiChild->AddRef();
|
|
ptiChild->RemoveFromAllLists();
|
|
ptiChild->Release();
|
|
} // if: child not deleted yet
|
|
} // if: child lives in the tree
|
|
|
|
} // Remove the item from the list of tree items
|
|
|
|
} //*** CTreeItem::RemoveChild()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PtiChildFromName
|
|
//
|
|
// Routine Description:
|
|
// Find a child tree item from its name.
|
|
//
|
|
// Arguments:
|
|
// rstrName [IN] Name of the item.
|
|
// ppos [OUT] Position of the item in the list.
|
|
//
|
|
// Return Value:
|
|
// ptiChild Child item corresponding to the specified name.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItem::PtiChildFromName(
|
|
IN const CString & rstrName,
|
|
OUT POSITION * ppos // = NULL
|
|
) const
|
|
{
|
|
POSITION posPtiChild;
|
|
POSITION posCurPtiChild;
|
|
CTreeItem * ptiChild = NULL;
|
|
|
|
// Loop through each child item to find the specified item.
|
|
posPtiChild = LptiChildren().GetHeadPosition();
|
|
while (posPtiChild != NULL)
|
|
{
|
|
posCurPtiChild = posPtiChild;
|
|
ptiChild = LptiChildren().GetNext(posPtiChild);
|
|
ASSERT_VALID(ptiChild);
|
|
|
|
if (ptiChild->StrName() == rstrName)
|
|
{
|
|
if (ppos != NULL)
|
|
*ppos = posCurPtiChild;
|
|
break;
|
|
} // if: found a match
|
|
} // while: more children of this tree item
|
|
|
|
return ptiChild;
|
|
|
|
} //*** CTreeItem::PtiChildFromName(CString&)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PtiChildFromName
|
|
//
|
|
// Routine Description:
|
|
// Find a child tree item from its name.
|
|
//
|
|
// Arguments:
|
|
// idsName [IN] ID of the name of the item.
|
|
// ppos [OUT] Position of the item in the list.
|
|
//
|
|
// Return Value:
|
|
// ptiChild Child item corresponding to the specified name.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItem::PtiChildFromName(
|
|
IN IDS idsName,
|
|
OUT POSITION * ppos // = NULL
|
|
) const
|
|
{
|
|
CString strName;
|
|
|
|
VERIFY(strName.LoadString(idsName));
|
|
return PtiChildFromName(strName, ppos);
|
|
|
|
} //*** CTreeItem::PtiChildFromName(IDS)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PtiChildFromPci
|
|
//
|
|
// Routine Description:
|
|
// Find a child tree item from its cluster item.
|
|
//
|
|
// Arguments:
|
|
// pci [IN] Cluster item to search for.
|
|
//
|
|
// Return Value:
|
|
// ptiChild Child item corresponding to the specified cluster item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItem * CTreeItem::PtiChildFromPci(IN const CClusterItem * pci) const
|
|
{
|
|
POSITION posPtiChild;
|
|
CTreeItem * ptiChild = NULL;
|
|
|
|
ASSERT_VALID(pci);
|
|
|
|
// Loop through each child item to find the specified item.
|
|
posPtiChild = LptiChildren().GetHeadPosition();
|
|
while (posPtiChild != NULL)
|
|
{
|
|
ptiChild = LptiChildren().GetNext(posPtiChild);
|
|
ASSERT_VALID(ptiChild);
|
|
|
|
if (ptiChild->Pci() == pci)
|
|
break;
|
|
} // while: more children of this tree item
|
|
|
|
return ptiChild;
|
|
|
|
} //*** CTreeItem::PtiChildFromPci()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PliChildFromPci
|
|
//
|
|
// Routine Description:
|
|
// Find a child list item from its cluster item.
|
|
//
|
|
// Arguments:
|
|
// pci [IN] Cluster item to search for.
|
|
//
|
|
// Return Value:
|
|
// pliChild Child item corresponding to the specified cluster item.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CListItem * CTreeItem::PliChildFromPci(IN const CClusterItem * pci) const
|
|
{
|
|
POSITION posPliChild;
|
|
CListItem * pliChild = NULL;
|
|
|
|
// Loop through each child item to find the specified item.
|
|
posPliChild = LpliChildren().GetHeadPosition();
|
|
while (posPliChild != NULL)
|
|
{
|
|
pliChild = LpliChildren().GetNext(posPliChild);
|
|
ASSERT_VALID(pliChild);
|
|
|
|
if (pliChild->Pci() == pci)
|
|
break;
|
|
} // while: more children of this tree item
|
|
|
|
return pliChild;
|
|
|
|
} //*** CTreeItem::PliChildFromPci()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::HtiInsertInTree
|
|
//
|
|
// Routine Description:
|
|
// Insert the item in a tree under the specified parent.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN OUT] Cluster tree view in which item is displayed.
|
|
//
|
|
// Return Value:
|
|
// m_hti Handle of the new item in the tree.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HTREEITEM CTreeItem::HtiInsertInTree(
|
|
IN OUT CClusterTreeView * pctv
|
|
)
|
|
{
|
|
CTreeItemContext * ptic;
|
|
HTREEITEM htiParent;
|
|
CSplitterFrame * pframe;
|
|
|
|
ASSERT_VALID(pctv);
|
|
ASSERT_VALID(Pci());
|
|
|
|
// Get the frame pointer.
|
|
pframe = (CSplitterFrame *) pctv->GetParent()->GetParent();
|
|
ASSERT_VALID(pframe);
|
|
|
|
// Get the tree item context for this item.
|
|
// If it doesn't exist yet, create one.
|
|
ptic = PticFromView(pctv);
|
|
if (ptic == NULL)
|
|
{
|
|
// Create the new tree item context.
|
|
ptic = new CTreeItemContext(pframe, this, NULL, FALSE /*bExpanded*/);
|
|
if (ptic == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
} // if: error allcoating the tree item context
|
|
ASSERT_VALID(ptic);
|
|
ptic->Init();
|
|
m_lptic.AddTail(ptic);
|
|
} // if: no entry found
|
|
|
|
// Get our parent's handle.
|
|
if (PtiParent() != NULL)
|
|
{
|
|
CTreeItemContext * pticParent;
|
|
|
|
pticParent = PtiParent()->PticFromFrame(pframe);
|
|
ASSERT_VALID(pticParent);
|
|
htiParent = pticParent->m_hti;
|
|
} // if: parent specified
|
|
else
|
|
htiParent = NULL;
|
|
|
|
// Insert the item in the tree.
|
|
{
|
|
CTreeCtrl * ptc;
|
|
CString strName;
|
|
|
|
ASSERT_VALID(pframe->PviewTree());
|
|
|
|
Pci()->GetTreeName(strName);
|
|
|
|
ptc = &pframe->PviewTree()->GetTreeCtrl();
|
|
VERIFY((ptic->m_hti = ptc->InsertItem(strName, htiParent)) != NULL);
|
|
VERIFY(ptc->SetItemData(ptic->m_hti, (DWORD_PTR) this));
|
|
} // Insert the item in the tree
|
|
|
|
UpdateState();
|
|
return ptic->m_hti;
|
|
|
|
} //*** CTreeItem::HtiInsertInTree()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::RemoveFromAllLists
|
|
//
|
|
// Routine Description:
|
|
// Remove this item from all lists.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::RemoveFromAllLists(void)
|
|
{
|
|
if (Pci() != NULL)
|
|
{
|
|
ASSERT_VALID(Pci());
|
|
|
|
// Loop through each view and remove the item from the list.
|
|
{
|
|
POSITION posPtic;
|
|
POSITION posPticPrev;
|
|
CTreeItemContext * ptic;
|
|
CTreeCtrl * ptc;
|
|
CClusterListView * pviewList;
|
|
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
// Get the next tree item context list entry.
|
|
posPticPrev = posPtic;
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
|
|
// Get the tree control and list view from the frame.
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
ptc = &ptic->m_pframe->PviewTree()->GetTreeCtrl();
|
|
pviewList = ptic->m_pframe->PviewList();
|
|
|
|
// If this tree item is the parent of the list control items,
|
|
// refresh the list control with no selection.
|
|
if (pviewList->PtiParent() == this)
|
|
pviewList->Refresh(NULL);
|
|
|
|
// Delete the item from the tree control and the list.
|
|
VERIFY(ptc->DeleteItem(ptic->m_hti));
|
|
m_lptic.RemoveAt(posPticPrev);
|
|
delete ptic;
|
|
} // while: more lists
|
|
} // Loop through each view and remove the item from the list
|
|
|
|
// Remove ourselves from the cluster item's list.
|
|
Pci()->RemoveTreeItem(this);
|
|
} // if: valid cluster item pointer
|
|
|
|
} //*** CTreeItem::RemoveFromAllLists()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::Select
|
|
//
|
|
// Routine Description:
|
|
// Select this item in the specified tree view. This causes the
|
|
// children of this item to be displayed in a list view.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN OUT] Tree view in which item was selected.
|
|
// bSelectInTree [IN] TRUE = select in tree control also.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::Select(IN OUT CClusterTreeView * pctv, IN BOOL bSelectInTree)
|
|
{
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pctv);
|
|
|
|
// Get the tree item context.
|
|
ptic = PticFromView(pctv);
|
|
ASSERT_VALID(ptic);
|
|
Trace(g_tagTreeItemSelect, _T("'%s' selected"), Pci()->StrName());
|
|
|
|
// Select the item in the tree control.
|
|
if (bSelectInTree)
|
|
ptic->m_pframe->PviewTree()->GetTreeCtrl().Select(ptic->m_hti, TVGN_CARET);
|
|
|
|
// Refresh the list control.
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
ASSERT_VALID(ptic->m_pframe->PviewList());
|
|
ptic->m_pframe->PviewList()->Refresh(this);
|
|
|
|
} //*** CTreeItem::Select()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PreRemoveFromFrameWithChildren
|
|
//
|
|
// Routine Description:
|
|
// Cleanup an item and all its children.
|
|
//
|
|
// Arguments:
|
|
// pframe [IN OUT] Frame window item is being removed from.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::PreRemoveFromFrameWithChildren(IN OUT CSplitterFrame * pframe)
|
|
{
|
|
POSITION posChild;
|
|
CTreeItem * ptiChild;
|
|
|
|
ASSERT_VALID(this);
|
|
|
|
// Cleanup all child items.
|
|
posChild = LptiChildren().GetHeadPosition();
|
|
while (posChild != NULL)
|
|
{
|
|
ptiChild = LptiChildren().GetNext(posChild);
|
|
ASSERT_VALID(ptiChild);
|
|
ptiChild->PreRemoveFromFrameWithChildren(pframe);
|
|
} // while: more items in the list
|
|
|
|
// Cleanup this item.
|
|
PreRemoveFromFrame(pframe);
|
|
|
|
} //*** CTreeItem::PreRemoveFromFrameWithChildren()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PreRemoveFromFrame
|
|
//
|
|
// Routine Description:
|
|
// Prepare to remove the item from a tree.
|
|
//
|
|
// Arguments:
|
|
// pframe [IN OUT] Frame window item is being removed from.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::PreRemoveFromFrame(IN OUT CSplitterFrame * pframe)
|
|
{
|
|
CTreeItemContext * ptic;
|
|
POSITION posPtic;
|
|
|
|
ASSERT_VALID(pframe);
|
|
|
|
// Find the view in our list.
|
|
ptic = PticFromFrame(pframe);
|
|
if (ptic == NULL)
|
|
return;
|
|
ASSERT_VALID(ptic);
|
|
VERIFY((posPtic = Lptic().Find(ptic)) != NULL);
|
|
|
|
// Remove the view from the list.
|
|
m_lptic.RemoveAt(posPtic);
|
|
|
|
// Delete the context item.
|
|
delete ptic;
|
|
|
|
} //*** CTreeItem::PreRemoveFromFrame(pframe)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PticFromFrame
|
|
//
|
|
// Routine Description:
|
|
// Find a tree item context from a frame.
|
|
//
|
|
// Arguments:
|
|
// pframe [IN] Frame to search on.
|
|
//
|
|
// Return Value:
|
|
// ptic Found context, or NULL if not found.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItemContext * CTreeItem::PticFromFrame(IN const CSplitterFrame * pframe) const
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pframe);
|
|
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
if (ptic->m_pframe == pframe)
|
|
return ptic;
|
|
} // while: more items in the list
|
|
|
|
return NULL;
|
|
|
|
} //*** CTreeItem::PticFromFrame()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PticFromView
|
|
//
|
|
// Routine Description:
|
|
// Find a tree item context from a tree view.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN] Tree view to search on.
|
|
//
|
|
// Return Value:
|
|
// ptic Found context, or NULL if not found.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItemContext * CTreeItem::PticFromView(IN const CClusterTreeView * pctv) const
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pctv);
|
|
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
if (ptic->m_pframe->PviewTree() == pctv)
|
|
return ptic;
|
|
} // while: more items in the list
|
|
|
|
return NULL;
|
|
|
|
} //*** CTreeItem::PticFromView(CClusterTreeView*)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PticFromView
|
|
//
|
|
// Routine Description:
|
|
// Find a tree item context from a list view.
|
|
//
|
|
// Arguments:
|
|
// pclv [IN] List view to search on.
|
|
//
|
|
// Return Value:
|
|
// ptic Found context, or NULL if not found.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CTreeItemContext * CTreeItem::PticFromView(IN const CClusterListView * pclv) const
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pclv);
|
|
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
if (ptic->m_pframe->PviewList() == pclv)
|
|
return ptic;
|
|
} // while: more items in the list
|
|
|
|
return NULL;
|
|
|
|
} //*** CTreeItem::PticFromView(CClusterListView*)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::HtiFromView
|
|
//
|
|
// Routine Description:
|
|
// Find a tree item handle from a view.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN] View to search on.
|
|
//
|
|
// Return Value:
|
|
// hti Found tree item handle, or NULL if not found.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HTREEITEM CTreeItem::HtiFromView(IN const CClusterTreeView * pctv) const
|
|
{
|
|
CTreeItemContext * ptic;
|
|
HTREEITEM hti = NULL;
|
|
|
|
ASSERT_VALID(pctv);
|
|
|
|
ptic = PticFromView(pctv);
|
|
if (ptic != NULL)
|
|
hti = ptic->m_hti;
|
|
|
|
return hti;
|
|
|
|
} //*** CTreeItem::HtiFromView()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PcoliAddColumn
|
|
//
|
|
// Routine Description:
|
|
// Add a column to the list of column header items.
|
|
//
|
|
// Arguments:
|
|
// rstrText [IN] Reference to the text of the column.
|
|
// idsColumnID [IN] ID of the column to identify the data.
|
|
// nDefaultWidth [IN] Default width of the column.
|
|
// nWidth [IN] Actual width of the column.
|
|
//
|
|
// Return Value:
|
|
// pcoli Column item added to the list.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CColumnItem * CTreeItem::PcoliAddColumn(
|
|
IN const CString & rstrText,
|
|
IN IDS idsColumnID,
|
|
IN int nDefaultWidth,
|
|
IN int nWidth
|
|
)
|
|
{
|
|
CColumnItem * pcoli;
|
|
|
|
pcoli = new CColumnItem(rstrText, idsColumnID, nDefaultWidth, nWidth);
|
|
if (pcoli == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
} // if: error allocating the column item
|
|
m_lpcoli.AddTail(pcoli);
|
|
|
|
return pcoli;
|
|
|
|
} //*** CTreeItem::PcoliAddColumn(CString&)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::PcoliAddColumn
|
|
//
|
|
// Routine Description:
|
|
// Add a column to the list of column header items.
|
|
//
|
|
// Arguments:
|
|
// idsText [IN] String resource ID for the text of the column.
|
|
// Also used as the column ID.
|
|
// nDefaultWidth [IN] Default width of the column.
|
|
// nWidth [IN] Actual width of the column.
|
|
//
|
|
// Return Value:
|
|
// pcoli Column item added to the list.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CColumnItem * CTreeItem::PcoliAddColumn(IN IDS idsText, IN int nDefaultWidth, IN int nWidth)
|
|
{
|
|
CString strText;
|
|
|
|
strText.LoadString(idsText);
|
|
return PcoliAddColumn(strText, idsText, nDefaultWidth, nWidth);
|
|
|
|
} //*** CTreeItem::PcoliAddColumn(IDS)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::BSelectItem
|
|
//
|
|
// Routine Description:
|
|
// Select the item in the specified tree control.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN OUT] Cluster tree view in which to select the item.
|
|
//
|
|
// Return Value:
|
|
// TRUE Item was selected successfully.
|
|
// FALSE Item not selected.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeItem::BSelectItem(IN OUT CClusterTreeView * pctv)
|
|
{
|
|
HTREEITEM hti;
|
|
|
|
ASSERT_VALID(pctv);
|
|
|
|
VERIFY((hti = HtiFromView(pctv)) != NULL);
|
|
return (pctv->GetTreeCtrl().SelectItem(hti) != 0);
|
|
|
|
} //*** CTreeItem::BSelectItem()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::SelectInAllViews
|
|
//
|
|
// Routine Description:
|
|
// Select this item in all views in which it is being displayed. This
|
|
// causes the children of this item to be displayed in a list view.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::SelectInAllViews(void)
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * ptic;
|
|
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
// Get the next tree item context list entry.
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
|
|
// Select the item in this list.
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
BSelectItem(ptic->m_pframe->PviewTree());
|
|
ptic->m_pframe->PviewTree()->SetFocus();
|
|
} // while: more items in the list
|
|
|
|
} //*** CTreeItem::SelectInAllViews()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::BExpand
|
|
//
|
|
// Routine Description:
|
|
// Expand the item in the specified tree control.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN OUT] Cluster tree view in which to expand the item.
|
|
// nCode [IN] Flag indicating the type of action to be taken.
|
|
//
|
|
// Return Value:
|
|
// TRUE Item was expanded successfully.
|
|
// FALSE Item not expanded.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeItem::BExpand(IN OUT CClusterTreeView * pctv, IN UINT nCode)
|
|
{
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pctv);
|
|
ASSERT(nCode != 0);
|
|
|
|
ptic = PticFromView(pctv);
|
|
ASSERT_VALID(ptic);
|
|
if (nCode == TVE_EXPAND)
|
|
ptic->m_bExpanded = TRUE;
|
|
else
|
|
ptic->m_bExpanded = FALSE;
|
|
return (pctv->GetTreeCtrl().Expand(ptic->m_hti, nCode) != 0);
|
|
|
|
} //*** CTreeItem::BExpand()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::ExpandInAllViews
|
|
//
|
|
// Routine Description:
|
|
// Expand the item in all views in which it is displayed.
|
|
//
|
|
// Arguments:
|
|
// nCode [IN] Flag indicating the type of action to be taken.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::ExpandInAllViews(IN UINT nCode)
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT(nCode != 0);
|
|
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
// Get the next tree item context list entry.
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
|
|
// Select the item in this list.
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
BExpand(ptic->m_pframe->PviewTree(), nCode);
|
|
} // while: more items in the list
|
|
|
|
} //*** CTreeItem::ExpandInAllViews()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::SetExpandedState
|
|
//
|
|
// Routine Description:
|
|
// Save the expanded state of the item in the specified view.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN] Tree view in which expanded state is being saved.
|
|
// bExpanded [IN] TRUE = item is expanded in the specified view.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::SetExpandedState(
|
|
IN const CClusterTreeView * pctv,
|
|
IN BOOL bExpanded
|
|
)
|
|
{
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pctv);
|
|
|
|
ptic = PticFromView(pctv);
|
|
ASSERT_VALID(ptic);
|
|
ptic->m_bExpanded = bExpanded;
|
|
|
|
} //*** CTreeItem::SetExpandedState()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::BShouldBeExpanded
|
|
//
|
|
// Routine Description:
|
|
// Returns whether the item should be expanded in the specified tree
|
|
// view based on the user's profile.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN] Tree view in which expanded state is being saved.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeItem::BShouldBeExpanded(IN const CClusterTreeView * pctv) const
|
|
{
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pctv);
|
|
|
|
ptic = PticFromView(pctv);
|
|
ASSERT_VALID(ptic);
|
|
return ptic->m_bExpanded;
|
|
|
|
} //*** CTreeItem::BShouldBeExpanded()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::UpdateState
|
|
//
|
|
// Routine Description:
|
|
// Update the current state of the item.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::UpdateState(void)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(Pci());
|
|
|
|
// Ask the item to update its state.
|
|
if (Pci() != NULL)
|
|
Pci()->UpdateState();
|
|
|
|
} //*** CTreeItem::UpdateState()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::UpdateAllStatesInTree
|
|
//
|
|
// Routine Description:
|
|
// Update the current state of the item.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::UpdateAllStatesInTree(void)
|
|
{
|
|
POSITION posPti;
|
|
CTreeItem * ptiChild;
|
|
|
|
UpdateState();
|
|
posPti = LptiChildren().GetHeadPosition();
|
|
while (posPti != NULL)
|
|
{
|
|
ptiChild = LptiChildren().GetNext(posPti);
|
|
ASSERT_VALID(ptiChild);
|
|
ptiChild->UpdateAllStatesInTree();
|
|
} // while: more children
|
|
|
|
} //*** CTreeItem::UpdateAllStatesInTree()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::UpdateUIState
|
|
//
|
|
// Routine Description:
|
|
// Update the current UI state of the item.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::UpdateUIState(void)
|
|
{
|
|
POSITION posPtic;
|
|
CTreeItemContext * ptic;
|
|
UINT nMask;
|
|
UINT nImage;
|
|
#ifdef _DISPLAY_STATE_TEXT_IN_TREE
|
|
CString strText;
|
|
#endif
|
|
|
|
ASSERT_VALID(Pci());
|
|
|
|
// Loop through the views and update the state on each one.
|
|
posPtic = Lptic().GetHeadPosition();
|
|
while (posPtic != NULL)
|
|
{
|
|
ptic = Lptic().GetNext(posPtic);
|
|
ASSERT_VALID(ptic);
|
|
|
|
// Set the images that are displayed for the item.
|
|
ASSERT_VALID(ptic->m_pframe);
|
|
ASSERT_VALID(ptic->m_pframe->PviewTree());
|
|
nMask = TVIF_TEXT;
|
|
if (Pci() == NULL)
|
|
{
|
|
#ifdef _DISPLAY_STATE_TEXT_IN_TREE
|
|
strText = StrName();
|
|
#endif
|
|
nImage = 0;
|
|
} // if: invalid cluster item
|
|
else
|
|
{
|
|
nMask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
|
#ifdef _DISPLAY_STATE_TEXT_IN_TREE
|
|
Pci()->GetTreeName(strText);
|
|
#endif
|
|
nImage = Pci()->IimgState();
|
|
} // else: valid cluster item
|
|
#ifdef _DISPLAY_STATE_TEXT_IN_TREE
|
|
Trace(g_tagTreeItemUpdate, _T("Updating item '%s' (pci name = '%s')"), strText, Pci()->StrName());
|
|
#else
|
|
Trace(g_tagTreeItemUpdate, _T("Updating item '%s' (pci name = '%s')"), StrName(), Pci()->StrName());
|
|
#endif
|
|
ptic->m_pframe->PviewTree()->GetTreeCtrl().SetItem(
|
|
ptic->m_hti, // hItem
|
|
nMask, // nMask
|
|
#ifdef _DISPLAY_STATE_TEXT_IN_TREE
|
|
strText, // lpszItem
|
|
#else
|
|
StrName(), // lpszItem
|
|
#endif
|
|
nImage, // nImage
|
|
nImage, // nSelectedImage
|
|
0, // nState
|
|
0, // nStatemask
|
|
NULL // lParam
|
|
);
|
|
} // while: more view
|
|
|
|
} //*** CTreeItem::UpdateUIState()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::OnCmdMsg
|
|
//
|
|
// Routine Description:
|
|
// Processes command messages. Attempts to pass them on to a selected
|
|
// item first.
|
|
//
|
|
// Arguments:
|
|
// nID [IN] Command ID.
|
|
// nCode [IN] Notification code.
|
|
// pExtra [IN OUT] Used according to the value of nCode.
|
|
// pHandlerInfo [OUT] ???
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeItem::OnCmdMsg(
|
|
UINT nID,
|
|
int nCode,
|
|
void * pExtra,
|
|
AFX_CMDHANDLERINFO * pHandlerInfo
|
|
)
|
|
{
|
|
if (Pci() != NULL)
|
|
{
|
|
// Give the cluster item a chance to handle the message.
|
|
if (Pci()->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
|
|
return TRUE;
|
|
} // if: valid cluster item
|
|
|
|
return CBaseCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
|
|
|
|
} //*** CTreeItem::OnCmdMsg()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::OpenChild
|
|
//
|
|
// Routine Description:
|
|
// Open the specified child item.
|
|
//
|
|
// Arguments:
|
|
// pti [IN OUT] Child tree item to open.
|
|
// pframe [IN OUT] Frame in which to open the item.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::OpenChild(
|
|
IN OUT CTreeItem * pti,
|
|
IN OUT CSplitterFrame * pframe
|
|
)
|
|
{
|
|
CTreeItemContext * ptic;
|
|
|
|
ASSERT_VALID(pti);
|
|
ASSERT_VALID(pframe);
|
|
|
|
// Find the tree item context for the frame.
|
|
ptic = PticFromFrame(pframe);
|
|
ASSERT_VALID(ptic);
|
|
|
|
// Expand the parent item and then select the child item.
|
|
if (pframe->PviewTree()->GetTreeCtrl().Expand(ptic->m_hti, TVE_EXPAND))
|
|
pti->Select(pframe->PviewTree(), TRUE /*bSelectInTree*/);
|
|
|
|
} //*** CTreeItem::OpenChild()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItem::EditLabel
|
|
//
|
|
// Routine Description:
|
|
// Processes the ID_FILE_RENAME menu command.
|
|
//
|
|
// Arguments:
|
|
// pctv [IN OUT] Cluster tree view item is being edited in.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItem::EditLabel(IN OUT CClusterTreeView * pctv)
|
|
{
|
|
HTREEITEM hti;
|
|
|
|
ASSERT_VALID(pctv);
|
|
ASSERT_VALID(Pci());
|
|
ASSERT(Pci()->BCanBeEdited());
|
|
|
|
hti = HtiFromView(pctv);
|
|
ASSERT(hti != NULL);
|
|
pctv->GetTreeCtrl().EditLabel(hti);
|
|
|
|
} //*** CTreeItem::EditLabel()
|
|
|
|
|
|
//***************************************************************************
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTreeItemContext
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
IMPLEMENT_DYNCREATE(CTreeItemContext, CObject)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItemContext::Init
|
|
//
|
|
// Routine Description:
|
|
// Initialize the tree item context.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItemContext::Init(void)
|
|
{
|
|
BOOL bExpanded;
|
|
UINT cbColumnInfo;
|
|
CString strValueName;
|
|
|
|
ASSERT_VALID(m_pti);
|
|
ASSERT(m_pti->StrProfileSection().GetLength() > 0);
|
|
ASSERT(m_prgnColumnInfo == NULL);
|
|
|
|
try
|
|
{
|
|
// Read the expanded state.
|
|
m_pframe->ConstructProfileValueName(strValueName, REGPARAM_EXPANDED);
|
|
bExpanded = AfxGetApp()->GetProfileInt(
|
|
m_pti->StrProfileSection(),
|
|
strValueName,
|
|
m_bExpanded
|
|
);
|
|
if (bExpanded)
|
|
m_bExpanded = bExpanded;
|
|
|
|
// Read the column information.
|
|
m_pframe->ConstructProfileValueName(strValueName, REGPARAM_COLUMNS);
|
|
AfxGetApp()->GetProfileBinary(
|
|
m_pti->StrProfileSection(),
|
|
strValueName,
|
|
(BYTE **) &m_prgnColumnInfo,
|
|
&cbColumnInfo
|
|
);
|
|
} // try
|
|
catch (CException * pe)
|
|
{
|
|
pe->Delete();
|
|
} // catch: CException
|
|
|
|
} //*** CTreeItemContext::Init()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItemContext::SaveProfileInfo
|
|
//
|
|
// Routine Description:
|
|
// Save state information to the user's profile. This includes column
|
|
// widths and positions as well as whether the tree item was expanded
|
|
// or not.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CTreeItemContext::SaveProfileInfo(void)
|
|
{
|
|
CString strValueName;
|
|
|
|
try
|
|
{
|
|
ASSERT_VALID(m_pti);
|
|
ASSERT(m_pti->StrProfileSection().GetLength() > 0);
|
|
|
|
// Save expansion info to the user's profile.
|
|
m_pframe->ConstructProfileValueName(strValueName, REGPARAM_EXPANDED);
|
|
AfxGetApp()->WriteProfileInt(
|
|
m_pti->StrProfileSection(),
|
|
strValueName,
|
|
m_bExpanded
|
|
);
|
|
|
|
if (m_prgnColumnInfo != NULL)
|
|
{
|
|
// Save column info to the user's profile.
|
|
m_pframe->ConstructProfileValueName(strValueName, REGPARAM_COLUMNS);
|
|
AfxGetApp()->WriteProfileBinary(
|
|
m_pti->StrProfileSection(),
|
|
strValueName,
|
|
(PBYTE) m_prgnColumnInfo,
|
|
((m_prgnColumnInfo[0] * 2) + 1) * sizeof(DWORD)
|
|
);
|
|
} // if: there is column info
|
|
} // try
|
|
catch (CException * pe)
|
|
{
|
|
pe->Delete();
|
|
} // catch: CException
|
|
|
|
} //*** CTreeItemContext::SaveProfileInfo()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItemContext::PrgnColumnInfo
|
|
//
|
|
// Routine Description:
|
|
// Return the column info. If it doesn't exist or isn't the right
|
|
// size, allocate one.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// prgnColumnInfo The column info array.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD * CTreeItemContext::PrgnColumnInfo(void)
|
|
{
|
|
DWORD cColumns;
|
|
|
|
ASSERT_VALID(m_pti);
|
|
|
|
cColumns = (DWORD)m_pti->Lpcoli().GetCount();
|
|
|
|
if ((m_prgnColumnInfo == NULL)
|
|
|| (cColumns != m_prgnColumnInfo[0]))
|
|
{
|
|
DWORD cnColumnInfo = (cColumns * 2) + 1;
|
|
delete [] m_prgnColumnInfo;
|
|
m_prgnColumnInfo = new DWORD[cnColumnInfo];
|
|
if (m_prgnColumnInfo == NULL)
|
|
{
|
|
ThrowStaticException(GetLastError());
|
|
} // if: error allocating column info array
|
|
|
|
//
|
|
// Initialize the column info array
|
|
//
|
|
{
|
|
DWORD inColumnInfo;
|
|
|
|
// The first entry is the number of columns.
|
|
m_prgnColumnInfo[0] = cColumns;
|
|
|
|
// The second set of entries is the width of each column.
|
|
{
|
|
POSITION pos;
|
|
CColumnItem * pcoli;
|
|
|
|
inColumnInfo = 1;
|
|
pos = m_pti->Lpcoli().GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
pcoli = m_pti->Lpcoli().GetNext(pos);
|
|
ASSERT_VALID(pcoli);
|
|
|
|
ASSERT(inColumnInfo <= cColumns);
|
|
m_prgnColumnInfo[inColumnInfo++] = pcoli->NWidth();
|
|
} // while: more items in the list
|
|
} // The second set of entries is the width of each column
|
|
|
|
// The third set of entries is the order of the columns.
|
|
{
|
|
DWORD * prgnColumnInfo = &m_prgnColumnInfo[inColumnInfo];
|
|
for (inColumnInfo = 0 ; inColumnInfo < cColumns ; inColumnInfo++)
|
|
prgnColumnInfo[inColumnInfo] = inColumnInfo;
|
|
} // The third set of entries is the order of the columns
|
|
} // Initialize the column info array
|
|
} // if: column info array doesn't exist or is wrong size
|
|
|
|
return m_prgnColumnInfo;
|
|
|
|
} //*** CTreeItemContext::PrgnColumnInfo()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTreeItemContext::BIsExpanded
|
|
//
|
|
// Routine Description:
|
|
// Return the EXPANDED state of the item in this tree view.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// TRUE Item is expanded.
|
|
// FALSE Item is not expanded.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CTreeItemContext::BIsExpanded(void) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(m_pframe);
|
|
ASSERT_VALID(m_pframe->PviewTree());
|
|
ASSERT(m_hti != NULL);
|
|
return (m_pframe->PviewTree()->GetTreeCtrl().GetItemState(m_hti, TVIS_EXPANDED) == TVIS_EXPANDED);
|
|
|
|
} //*** CTreeItemContext::BIsExpanded()
|
|
|
|
|
|
//***************************************************************************
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Global Functions
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// DestructElements
|
|
//
|
|
// Routine Description:
|
|
// Destroys CTreeItem* elements.
|
|
//
|
|
// Arguments:
|
|
// pElements Array of pointers to elements to destruct.
|
|
// nCount Number of elements to destruct.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<>
|
|
void AFXAPI DestructElements(CTreeItem ** pElements, INT_PTR nCount)
|
|
{
|
|
ASSERT(nCount == 0 ||
|
|
AfxIsValidAddress(pElements, nCount * sizeof(CTreeItem *)));
|
|
|
|
// call the destructor(s)
|
|
for (; nCount--; pElements++)
|
|
{
|
|
ASSERT_VALID(*pElements);
|
|
(*pElements)->Release();
|
|
} // for: each item in the array
|
|
|
|
} //*** DestructElements(CTreeItem**)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// DeleteAllItemData
|
|
//
|
|
// Routine Description:
|
|
// Deletes all item data in a CList.
|
|
//
|
|
// Arguments:
|
|
// rlp [IN OUT] Reference to the list whose data is to be deleted.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void DeleteAllItemData(IN OUT CTreeItemList & rlp)
|
|
{
|
|
POSITION pos;
|
|
CTreeItem * pti;
|
|
|
|
// Delete all the items in the Contained list.
|
|
pos = rlp.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
pti = rlp.GetNext(pos);
|
|
ASSERT_VALID(pti);
|
|
// Trace(g_tagTreeItemDelete, _T("DeleteAllItemData(rlpti) - Deleting tree item '%s'"), pti->Pci()->StrName());
|
|
pti->Delete();
|
|
} // while: more items in the list
|
|
|
|
} //*** DeleteAllItemData()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// DeleteAllItemData
|
|
//
|
|
// Routine Description:
|
|
// Deletes all item data in a CList.
|
|
//
|
|
// Arguments:
|
|
// rlp [IN OUT] Reference to the list whose data is to be deleted.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void DeleteAllItemData(IN OUT CTreeItemContextList & rlp)
|
|
{
|
|
POSITION pos;
|
|
CTreeItemContext * ptic;
|
|
|
|
// Delete all the items in the Contained list.
|
|
pos = rlp.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
ptic = rlp.GetNext(pos);
|
|
ASSERT_VALID(ptic);
|
|
delete ptic;
|
|
} // while: more items in the list
|
|
|
|
} //*** DeleteAllItemData()
|