|
|
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c ) 1996-2000 Microsoft Corporation
//
// Module Name:
// ClusItem.cpp
//
// Description:
// Implementation of the CClusterItem class.
//
// Maintained By:
// David Potter (davidp ) May 6, 1996
//
// Revision History:
//
// Modified to fix bugs associated with open/close state of m_hkey.
// m_hkey will be closed upon destruction of CClusterItem.
// Roderick Sharper March 23, 1997.
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CluAdmin.h"
#include "ConstDef.h"
#include "ClusItem.h"
#include "ClusDoc.h"
#include "ExcOper.h"
#include "TraceTag.h"
#include "TreeItem.inl"
#include "PropList.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
CTraceTag g_tagClusItemCreate( _T("Create"), _T("CLUSTER ITEM CREATE"), 0 ); CTraceTag g_tagClusItemDelete( _T("Delete"), _T("CLUSTER ITEM DELETE"), 0 ); CTraceTag g_tagClusItemNotify( _T("Notify"), _T("CLUSTER ITEM NOTIFY"), 0 ); #endif
/////////////////////////////////////////////////////////////////////////////
// CClusterItemList
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItemList::PciFromName
//
// Routine Description:
// Find a cluster item in the list by its name.
//
// Arguments:
// pszName [IN] Name of item to look for.
// ppos [OUT] Position of the item in the list.
//
// Return Value:
// pci Cluster item corresponding the the specified name.
//
//--
/////////////////////////////////////////////////////////////////////////////
CClusterItem * CClusterItemList::PciFromName( IN LPCTSTR pszName, OUT POSITION * ppos // = NULL
) { POSITION posPci; POSITION posCurPci; CClusterItem * pci = NULL;
ASSERT( pszName != NULL );
posPci = GetHeadPosition( ); while ( posPci != NULL ) { posCurPci = posPci; pci = GetNext( posPci ); ASSERT_VALID( pci );
if ( pci->StrName( ).CompareNoCase( pszName ) == 0 ) { if ( ppos != NULL ) { *ppos = posCurPci; } // if
break; } // if: found a match
pci = NULL; } // while: more resources in the list
return pci;
} //*** CClusterItemList::PciFromName( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItemList::RemoveAll
//
// Routine Description:
// Remove all items from the list, decrementing the reference count
// on each one first.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Note:
// This routine is not virtual, so calls to the base class will
// not go through this routine. Also, it does not call the base
// class method.
//
//--
/////////////////////////////////////////////////////////////////////////////
#ifdef NEVER
void CClusterItemList::RemoveAll( void ) { ASSERT_VALID( this );
// destroy elements
CNode * pNode; for ( pNode = m_pNodeHead ; pNode != NULL ; pNode = pNode->pNext ) { // ((CClusterItem *) pNode->data)->Release( );
DestructElements( (CClusterItem**) &pNode->data, 1 ); } // for: each node in the list
// Call the base class method.
CObList::RemoveAll( );
} //*** CClusterItemList::RemoveAll( )
#endif
//***************************************************************************
/////////////////////////////////////////////////////////////////////////////
// CClusterItem
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE( CClusterItem, CBaseCmdTarget )
/////////////////////////////////////////////////////////////////////////////
// Message Maps
BEGIN_MESSAGE_MAP( CClusterItem, CBaseCmdTarget ) //{{AFX_MSG_MAP(CClusterItem)
ON_UPDATE_COMMAND_UI(ID_FILE_RENAME, OnUpdateRename) ON_UPDATE_COMMAND_UI(ID_FILE_PROPERTIES, OnUpdateProperties) ON_COMMAND(ID_FILE_PROPERTIES, OnCmdProperties) //}}AFX_MSG_MAP
END_MESSAGE_MAP( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::CClusterItem
//
// Routine Description:
// Default constructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CClusterItem::CClusterItem( void ) { CommonConstruct( );
} //*** CClusterItem::CClusterItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::CClusterItem
//
// Routine Description:
// Constructor.
//
// Arguments:
// pstrName [IN] Name of the item.
// idsType [IN] Type ID of the item.
// pstrDescription [IN] Description of the item.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CClusterItem::CClusterItem( IN const CString * pstrName, IN IDS idsType, IN const CString * pstrDescription ) { CommonConstruct( );
if ( pstrName != NULL ) { m_strName = *pstrName; } // if
if ( idsType == 0 ) { idsType = IDS_ITEMTYPE_CONTAINER; } // if
m_idsType = idsType; m_strType.LoadString( IdsType( ) );
if ( pstrDescription != NULL ) { m_strDescription = *pstrDescription; } // if
Trace( g_tagClusItemCreate, _T("CClusterItem( ) - Creating '%s' (%s )"), m_strName, m_strType );
} //*** CClusterItem::CClusterItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::CommonConstruct
//
// Routine Description:
// Common construction.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::CommonConstruct( void ) { m_hkey = NULL; m_idsType = IDS_ITEMTYPE_CONTAINER; m_strType.LoadString( IDS_ITEMTYPE_CONTAINER ); m_iimgObjectType = 0; m_iimgState = GetClusterAdminApp( )->Iimg( IMGLI_FOLDER ); m_pdoc = NULL; m_idmPopupMenu = 0; m_bDocObj = TRUE; m_bChanged = FALSE; m_bReadOnly = FALSE; m_pcnk = NULL;
} //*** CClusterItem::CommonConstruct( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::~CClusterItem
//
// Routine Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CClusterItem::~CClusterItem( void ) { Trace( g_tagClusItemDelete, _T("~CClusterItem( ) - Deleting cluster item '%s'"), StrName( ) );
// Empty the lists.
DeleteAllItemData( LptiBackPointers( ) ); DeleteAllItemData( LpliBackPointers( ) ); LptiBackPointers( ).RemoveAll( ); LpliBackPointers( ).RemoveAll( );
// Close the registry key.
if ( Hkey( ) != NULL ) { ClusterRegCloseKey( Hkey( ) ); m_hkey = NULL; } // if
// Remove the notification key and delete it.
if ( BDocObj( ) ) { POSITION pos;
pos = GetClusterAdminApp( )->Cnkl( ).Find( m_pcnk ); if ( pos != NULL ) { GetClusterAdminApp( )->Cnkl( ).RemoveAt( pos ); } // if
Trace( g_tagClusItemNotify, _T("~CClusterItem( ) - Deleting notification key (%08.8x ) for '%s'"), m_pcnk, StrName( ) ); delete m_pcnk; m_pcnk = NULL; } // if: object resides in the document
Trace( g_tagClusItemDelete, _T("~CClusterItem( ) - Done deleting cluster item '%s'"), StrName( ) );
} //*** CClusterItem::~CClusterItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::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 CClusterItem::Delete( void ) { // Add a reference so that we don't delete ourselves while
// still doing cleanup.
AddRef( );
// Cleanup this object.
Cleanup( );
// Remove the item from all lists and views.
CClusterItem::RemoveItem( );
// 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 ( ( Pdoc( ) != NULL ) && ( NReferenceCount( ) > 1 ) ) { if ( Pdoc( )->LpciToBeDeleted( ).Find( this ) == NULL ) { Pdoc( )->LpciToBeDeleted( ).AddTail( this ); } // if
} // 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( );
} //*** CClusterItem::Delete( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::Init
//
// Routine Description:
// Initialize the item.
//
// Arguments:
// pdoc [IN OUT] Document to which this item belongs.
// lpszName [IN] Name of the item.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by CNotifyKey::new( ) or
// CNotifyKeyList::AddTail( ).
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::Init( IN OUT CClusterDoc * pdoc, IN LPCTSTR lpszName ) { ASSERT_VALID( pdoc ); ASSERT( lpszName != NULL );
// Save parameters.
m_pdoc = pdoc; m_strName = lpszName;
Trace( g_tagClusItemCreate, _T("Init( ) - Initializing '%s' (%s )"), m_strName, m_strType );
// Find the notification key for this item in the document's list.
// If one is not found, allocate one.
if ( BDocObj( ) ) { POSITION pos; CClusterNotifyKey * pcnk = NULL;
pos = GetClusterAdminApp( )->Cnkl( ).GetHeadPosition( ); while ( pos != NULL ) { pcnk = GetClusterAdminApp( )->Cnkl( ).GetNext( pos ); if ( ( pcnk->m_cnkt == cnktClusterItem ) && ( pcnk->m_pci == this ) ) break; pcnk = NULL; } // while: more items in the list
// If a key was not found, allocate a new one.
if ( pcnk == NULL ) { pcnk = new CClusterNotifyKey( this, lpszName ); if ( pcnk == NULL ) { ThrowStaticException( GetLastError( ) ); } // if: error allocating the notify key
try { GetClusterAdminApp( )->Cnkl( ).AddTail( pcnk ); Trace( g_tagClusItemNotify, _T("Init( ) - Creating notification key (%08.8x ) for '%s'"), pcnk, StrName( ) ); } // try
catch ( ... ) { delete pcnk; throw; } // catch: anything
} // if: key wasn't found
m_pcnk = pcnk; } // if: object resides in the document
} //*** CClusterItem::Init( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::PlstrExtensions
//
// Routine Description:
// Return the list of admin extensions.
//
// Arguments:
// None.
//
// Return Value:
// plstr List of extensions.
// NULL No extension associated with this object.
//
// Exceptions Thrown:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
const CStringList * CClusterItem::PlstrExtensions( void ) const { return NULL;
} //*** CClusterItem::PlstrExtensions( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::RemoveItem
//
// Routine Description:
// Remove the item from all lists and views.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::RemoveItem( void ) { // Remove the item from each tree item.
{ POSITION posPti; CTreeItem * pti;
posPti = LptiBackPointers( ).GetHeadPosition( ); while ( posPti != NULL ) { pti = LptiBackPointers( ).GetNext( posPti ); ASSERT_VALID( pti ); ASSERT_VALID( pti->PtiParent( ) ); Trace( g_tagClusItemDelete, _T("RemoveItem( ) - Deleting tree item backptr from '%s' in '%s' - %d left"), StrName( ), pti->PtiParent( )->StrName( ), LptiBackPointers( ).GetCount( ) - 1 ); pti->RemoveItem( ); } // while: more items in the list
} // Remove the item from each tree item
// Remove the item from each list item.
{ POSITION posPli; CListItem * pli;
posPli = LpliBackPointers( ).GetHeadPosition( ); while ( posPli != NULL ) { pli = LpliBackPointers( ).GetNext( posPli ); ASSERT_VALID( pli ); ASSERT_VALID( pli->PtiParent( ) ); Trace( g_tagClusItemDelete, _T("RemoveItem( ) - Deleting list item backptr from '%s' in '%s' - %d left"), StrName( ), pli->PtiParent( )->StrName( ), LpliBackPointers( ).GetCount( ) - 1 ); pli->PtiParent( )->RemoveChild( pli->Pci( ) ); } // while: more items in the list
} // Remove the item from each tree item
} //*** CClusterItem::RemoveItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::WriteItem
//
// Routine Description:
// Write the item parameters to the cluster database.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by WriteItem( ).
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::WriteItem( void ) { } //*** CClusterItem::WriteItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::DwParseProperties
//
// Routine Description:
// Parse the properties of the resource. This is in a separate function
// from BInit so that the optimizer can do a better job.
//
// Arguments:
// rcpl [IN] Cluster property list to parse.
//
// Return Value:
// ERROR_SUCCESS Properties were parsed successfully.
//
// Exceptions Thrown:
// Any exceptions from CString::operator=( ).
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusterItem::DwParseProperties( IN const CClusPropList & rcpl ) { DWORD cProps; DWORD cprop; DWORD cbProps; const CObjectProperty * pprop; CLUSPROP_BUFFER_HELPER props; CLUSPROP_PROPERTY_NAME const * pName;
ASSERT( rcpl.PbPropList( ) != NULL );
props.pb = rcpl.PbPropList( ); cbProps = rcpl.CbPropList( );
// Loop through each property.
for ( cProps = *(props.pdw++ ) ; cProps > 0 ; cProps-- ) { pName = props.pName; ASSERT( pName->Syntax.dw == CLUSPROP_SYNTAX_NAME ); props.pb += sizeof( *pName ) + ALIGN_CLUSPROP( pName->cbLength );
// Decrement the counter by the size of the name.
ASSERT( cbProps > sizeof( *pName ) + ALIGN_CLUSPROP( pName->cbLength ) ); cbProps -= sizeof( *pName ) + ALIGN_CLUSPROP( pName->cbLength );
ASSERT( cbProps > sizeof( *props.pValue ) + ALIGN_CLUSPROP( props.pValue->cbLength ) );
// Parse known properties.
for ( pprop = Pprops( ), cprop = Cprops( ) ; cprop > 0 ; pprop++, cprop-- ) { if ( lstrcmpiW( pName->sz, pprop->m_pwszName ) == 0 ) { ASSERT( props.pSyntax->wFormat == pprop->m_propFormat ); switch ( pprop->m_propFormat ) { case CLUSPROP_FORMAT_SZ: ASSERT( ( props.pValue->cbLength == ( lstrlenW( props.pStringValue->sz ) + 1 ) * sizeof( WCHAR ) ) || ( (props.pValue->cbLength == 0 ) && ( props.pStringValue->sz[ 0 ] == L'\0' ) ) ); *pprop->m_valuePrev.pstr = props.pStringValue->sz; break; case CLUSPROP_FORMAT_DWORD: case CLUSPROP_FORMAT_LONG: ASSERT( props.pValue->cbLength == sizeof( DWORD ) ); *pprop->m_valuePrev.pdw = props.pDwordValue->dw; break; case CLUSPROP_FORMAT_BINARY: case CLUSPROP_FORMAT_MULTI_SZ: *pprop->m_valuePrev.ppb = props.pBinaryValue->rgb; *pprop->m_valuePrev.pcb = props.pBinaryValue->cbLength; break; default: ASSERT( 0 ); // don't know how to deal with this type
} // switch: property format
// Exit the loop since we found the parameter.
break; } // if: found a match
} // for: each property
// If the property wasn't known, ask the derived class to parse it.
if ( cprop == 0 ) { DWORD dwStatus;
dwStatus = DwParseUnknownProperty( pName->sz, props, cbProps ); if ( dwStatus != ERROR_SUCCESS ) { return dwStatus; } // if
} // if: property not parsed
// Advance the buffer pointer past the value in the value list.
while ( ( props.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK ) && ( cbProps > 0 ) ) { ASSERT( cbProps > sizeof( *props.pValue ) + ALIGN_CLUSPROP( props.pValue->cbLength ) ); cbProps -= sizeof( *props.pValue ) + ALIGN_CLUSPROP( props.pValue->cbLength ); props.pb += sizeof( *props.pValue ) + ALIGN_CLUSPROP( props.pValue->cbLength ); } // while: more values in the list
// Advance the buffer pointer past the value list endmark.
ASSERT( cbProps >= sizeof( *props.pSyntax ) ); cbProps -= sizeof( *props.pSyntax ); props.pb += sizeof( *props.pSyntax ); // endmark
} // for: each property
return ERROR_SUCCESS;
} //*** CClusterItem::DwParseProperties( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::SetCommonProperties
//
// Routine Description:
// Set the common properties for this object in the cluster database.
//
// Arguments:
// bValidateOnly [IN] Only validate the data.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by WriteItem( ).
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::SetCommonProperties( IN BOOL bValidateOnly ) { DWORD dwStatus = ERROR_SUCCESS; CClusPropList cpl; CWaitCursor wc;
// Save data.
{ // Build the property list and set the data.
try { BuildPropList( cpl ); dwStatus = DwSetCommonProperties( cpl, bValidateOnly ); } // try
catch ( CMemoryException * pme ) { pme->Delete( ); dwStatus = ERROR_NOT_ENOUGH_MEMORY; } // catch: CMemoryException
// Handle errors.
if ( dwStatus != ERROR_SUCCESS ) { if ( dwStatus != ERROR_RESOURCE_PROPERTIES_STORED ) { ThrowStaticException( dwStatus, IDS_APPLY_PARAM_CHANGES_ERROR ); } // if
} // if: error setting properties
if ( ! bValidateOnly && ( dwStatus == ERROR_SUCCESS ) ) { DWORD cprop; const CObjectProperty * pprop;
// Save new values as previous values.
for ( pprop = Pprops( ), cprop = Cprops( ) ; cprop > 0 ; pprop++, cprop-- ) { switch ( pprop->m_propFormat ) { case CLUSPROP_FORMAT_SZ: ASSERT( pprop->m_value.pstr != NULL ); ASSERT( pprop->m_valuePrev.pstr != NULL ); *pprop->m_valuePrev.pstr = *pprop->m_value.pstr; break; case CLUSPROP_FORMAT_DWORD: ASSERT( pprop->m_value.pdw != NULL ); ASSERT( pprop->m_valuePrev.pdw != NULL ); *pprop->m_valuePrev.pdw = *pprop->m_value.pdw; break; case CLUSPROP_FORMAT_BINARY: case CLUSPROP_FORMAT_MULTI_SZ: ASSERT( pprop->m_value.ppb != NULL ); ASSERT( *pprop->m_value.ppb != NULL ); ASSERT( pprop->m_value.pcb != NULL ); ASSERT( pprop->m_valuePrev.ppb != NULL ); ASSERT( *pprop->m_valuePrev.ppb != NULL ); ASSERT( pprop->m_valuePrev.pcb != NULL ); delete [] *pprop->m_valuePrev.ppb; *pprop->m_valuePrev.ppb = new BYTE[ *pprop->m_value.pcb ]; if ( *pprop->m_valuePrev.ppb == NULL ) { ThrowStaticException( GetLastError( ) ); } // if: error allocating data buffer
CopyMemory( *pprop->m_valuePrev.ppb, *pprop->m_value.ppb, *pprop->m_value.pcb ); *pprop->m_valuePrev.pcb = *pprop->m_value.pcb; break; default: ASSERT( 0 ); // don't know how to deal with this type
} // switch: property format
} // for: each property
} // if: not just validating and properties set successfully
if ( dwStatus == ERROR_RESOURCE_PROPERTIES_STORED ) { ThrowStaticException( dwStatus ); } // if
} // Save data
} //*** CClusterItem::SetCommonProperties( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::BuildPropList
//
// Routine Description:
// Build the property list.
//
// Arguments:
// rcpl [IN OUT] Cluster property list.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by CClusPropList::ScAddProp( ).
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::BuildPropList( IN OUT CClusPropList & rcpl ) { DWORD cprop; const CObjectProperty * pprop;
for ( pprop = Pprops( ), cprop = Cprops( ) ; cprop > 0 ; pprop++, cprop-- ) { switch ( pprop->m_propFormat ) { case CLUSPROP_FORMAT_SZ: rcpl.ScAddProp( pprop->m_pwszName, *pprop->m_value.pstr, *pprop->m_valuePrev.pstr ); break; case CLUSPROP_FORMAT_DWORD: rcpl.ScAddProp( pprop->m_pwszName, *pprop->m_value.pdw, *pprop->m_valuePrev.pdw ); break; case CLUSPROP_FORMAT_BINARY: case CLUSPROP_FORMAT_MULTI_SZ: rcpl.ScAddProp( pprop->m_pwszName, *pprop->m_value.ppb, *pprop->m_value.pcb, *pprop->m_valuePrev.ppb, *pprop->m_valuePrev.pcb ); break; default: ASSERT( 0 ); // don't know how to deal with this type
return; } // switch: property format
} // for: each property
} //*** CClusterItem::BuildPropList( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::UpdateState
//
// Routine Description:
// Update the current state of the item.
// Default implementation.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::UpdateState( void ) { // Update the state of all the tree items pointing to us.
{ POSITION pos; CTreeItem * pti;
pos = LptiBackPointers( ).GetHeadPosition( ); while ( pos != NULL ) { pti = LptiBackPointers( ).GetNext( pos ); ASSERT_VALID( pti ); pti->UpdateUIState( ); } // while: more items in the list
} // Update the state of all the tree items pointing to us
// Update the state of all the list items pointing to us.
{ POSITION pos; CListItem * pli;
pos = LpliBackPointers( ).GetHeadPosition( ); while ( pos != NULL ) { pli = LpliBackPointers( ).GetNext( pos ); ASSERT_VALID( pli ); pli->UpdateUIState( ); } // while: more items in the list
} // Update the state of all the tree items pointing to us
} //*** CClusterItem::UpdateState( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::DwReadValue
//
// Routine Description:
// Read a REG_SZ value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to read.
// pszKeyName [IN] Name of the key where the value resides.
// rstrValue [OUT] String in which to return the value.
//
// Return Value:
// dwStatus ERROR_SUCCESS = success, !0 = failure
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusterItem::DwReadValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, OUT CString & rstrValue ) { DWORD dwStatus; LPWSTR pwszValue = NULL; DWORD dwValueLen; DWORD dwValueType; HKEY hkey = NULL; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( Hkey( ) != NULL );
rstrValue.Empty( );
try { // Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_READ, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { return dwStatus; } // if
} // if: need to open a subkey
else { hkey = Hkey( ); } // else
// Get the size of the value.
dwValueLen = 0; dwStatus = ClusterRegQueryValue( hkey, pszValueName, &dwValueType, NULL, &dwValueLen ); if ( ( dwStatus == ERROR_SUCCESS ) || ( dwStatus == ERROR_MORE_DATA ) ) { ASSERT( dwValueType == REG_SZ );
// Allocate enough space for the data.
pwszValue = rstrValue.GetBuffer( dwValueLen / sizeof( WCHAR ) ); ASSERT( pwszValue != NULL ); dwValueLen += 1 * sizeof( WCHAR ); // Don't forget the final null-terminator.
// Read the value.
dwStatus = ClusterRegQueryValue( hkey, pszValueName, &dwValueType, (LPBYTE ) pwszValue, &dwValueLen ); if ( dwStatus == ERROR_SUCCESS ) { ASSERT( dwValueType == REG_SZ ); } // if: value read successfully
rstrValue.ReleaseBuffer( ); } // if: got the size successfully
} // try
catch ( CMemoryException * pme ) { pme->Delete( ); dwStatus = ERROR_NOT_ENOUGH_MEMORY; } // catch: CMemoryException
if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
return dwStatus;
} //*** CClusterItem::DwReadValue( LPCTSTR, CString& )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::DwReadValue
//
// Routine Description:
// Read a REG_MULTI_SZ value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to read.
// pszKeyName [IN] Name of the key where the value resides.
// rlstrValue [OUT] String list in which to return the values.
//
// Return Value:
// dwStatus ERROR_SUCCESS = success, !0 = failure
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusterItem::DwReadValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, OUT CStringList & rlstrValue ) { DWORD dwStatus; LPWSTR pwszValue = NULL; LPWSTR pwszCurValue; DWORD dwValueLen; DWORD dwValueType; HKEY hkey = NULL; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( Hkey( ) != NULL );
rlstrValue.RemoveAll( );
try { // Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_READ, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { return dwStatus; } // if
} // if: need to open a subkey
else hkey = Hkey( );
// Get the size of the value.
dwValueLen = 0; dwStatus = ClusterRegQueryValue( hkey, pszValueName, &dwValueType, NULL, &dwValueLen ); if ( ( dwStatus == ERROR_SUCCESS ) || ( dwStatus == ERROR_MORE_DATA ) ) { ASSERT( dwValueType == REG_MULTI_SZ );
// Allocate enough space for the data.
dwValueLen += 1 * sizeof( WCHAR ); // Don't forget the final null-terminator.
pwszValue = new WCHAR[ dwValueLen / sizeof( WCHAR ) ]; if ( pwszValue == NULL ) { AfxThrowMemoryException(); } // if: error allocating the value
// Read the value.
dwStatus = ClusterRegQueryValue( hkey, pszValueName, &dwValueType, (LPBYTE) pwszValue, &dwValueLen ); if ( dwStatus == ERROR_SUCCESS ) { ASSERT( dwValueType == REG_MULTI_SZ );
// Add each string from the value into the string list.
for ( pwszCurValue = pwszValue ; *pwszCurValue != L'\0' ; pwszCurValue += lstrlenW( pwszCurValue ) + 1 ) { rlstrValue.AddTail( pwszCurValue ); } // for
} // if: read the value successfully
} // if: got the size successfully
} // try
catch ( CMemoryException * pme ) { pme->Delete( ); dwStatus = ERROR_NOT_ENOUGH_MEMORY; } // catch: CMemoryException
delete [] pwszValue; if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
return dwStatus;
} //*** CClusterItem::DwReadValue( LPCTSTR, CStringList& )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::DwReadValue
//
// Routine Description:
// Read a REG_DWORD value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to read.
// pszKeyName [IN] Name of the key where the value resides.
// pdwValue [OUT] DWORD in which to return the value.
//
// Return Value:
// dwStatus ERROR_SUCCESS = success, !0 = failure
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusterItem::DwReadValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, OUT DWORD * pdwValue ) { DWORD dwStatus; DWORD dwValue; DWORD dwValueLen; DWORD dwValueType; HKEY hkey; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( pdwValue != NULL ); ASSERT( Hkey( ) != NULL );
// Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_READ, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { return dwStatus; } // if
} // if: need to open a subkey
else { hkey = Hkey( ); } // else
// Read the value.
dwValueLen = sizeof( dwValue ); dwStatus = ClusterRegQueryValue( hkey, pszValueName, &dwValueType, (LPBYTE) &dwValue, &dwValueLen ); if ( dwStatus == ERROR_SUCCESS ) { ASSERT( dwValueType == REG_DWORD ); ASSERT( dwValueLen == sizeof( dwValue ) ); *pdwValue = dwValue; } // if: value read successfully
if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
return dwStatus;
} //*** CClusterItem::DwReadValue( LPCTSTR, DWORD* )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::DwReadValue
//
// Routine Description:
// Read a REG_DWORD value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to read.
// pszKeyName [IN] Name of the key where the value resides.
// pdwValue [OUT] DWORD in which to return the value.
// dwDefault [IN] Default value if parameter not set.
//
// Return Value:
// dwStatus ERROR_SUCCESS = success, !0 = failure
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusterItem::DwReadValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, OUT DWORD * pdwValue, IN DWORD dwDefault ) { DWORD dwStatus; CWaitCursor wc;
// Read the value.
dwStatus = DwReadValue( pszValueName, pszKeyName, pdwValue ); if ( dwStatus == ERROR_FILE_NOT_FOUND ) { *pdwValue = dwDefault; dwStatus = ERROR_SUCCESS; } // if: value not set
return dwStatus;
} //*** CClusterItem::DwReadValue( LPCTSTR, DWORD*, DWORD )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::DwReadValue
//
// Routine Description:
// Read a REG_BINARY value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to read.
// pszKeyName [IN] Name of the key where the value resides.
// ppbValue [OUT] Pointer in which to return the data. Caller
// is responsible for deallocating the data.
//
// Return Value:
// dwStatus ERROR_SUCCESS = success, !0 = failure
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusterItem::DwReadValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, OUT LPBYTE * ppbValue ) { DWORD dwStatus; DWORD dwValueLen; DWORD dwValueType; LPBYTE pbValue = NULL; HKEY hkey; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( ppbValue != NULL ); ASSERT( Hkey( ) != NULL );
delete [] *ppbValue; *ppbValue = NULL;
// Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_READ, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { return dwStatus; } // if
} // if: need to open a subkey
else { hkey = Hkey( ); } // else
// Get the length of the value.
dwValueLen = 0; dwStatus = ClusterRegQueryValue( hkey, pszValueName, &dwValueType, NULL, &dwValueLen ); if ( ( dwStatus != ERROR_SUCCESS ) && ( dwStatus != ERROR_MORE_DATA ) ) { if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
return dwStatus; } // if: error getting the length
ASSERT( dwValueType == REG_BINARY );
// Allocate a buffer,
try { pbValue = new BYTE[ dwValueLen ]; if ( pbValue == NULL ) { AfxThrowMemoryException(); } // if: error allocating the buffer
} // try
catch ( CMemoryException * ) { if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
dwStatus = ERROR_NOT_ENOUGH_MEMORY; return dwStatus; } // catch: CMemoryException
// Read the value.
dwStatus = ClusterRegQueryValue( hkey, pszValueName, &dwValueType, pbValue, &dwValueLen ); if ( dwStatus == ERROR_SUCCESS ) { *ppbValue = pbValue; } // if
else { delete [] pbValue; } // else
if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
return dwStatus;
} //*** CClusterItem::DwReadValue( LPCTSTR, LPBYTE* )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::WriteValue
//
// Routine Description:
// Write a REG_SZ value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to write.
// pszKeyName [IN] Name of the key where the value resides.
// rstrValue [IN] Value data.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CNTException( dwStatus )
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::WriteValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, IN const CString & rstrValue ) { DWORD dwStatus; HKEY hkey; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( Hkey( ) != NULL );
// Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_ALL_ACCESS, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { ThrowStaticException( dwStatus ); } // if
} // if: need to open a subkey
else { hkey = Hkey( ); } // else
// Write the value.
dwStatus = ClusterRegSetValue( hkey, pszValueName, REG_SZ, (CONST BYTE *) (LPCTSTR) rstrValue, ( rstrValue.GetLength( ) + 1 ) * sizeof( WCHAR ) ); if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
if ( dwStatus != ERROR_SUCCESS ) { ThrowStaticException( dwStatus ); } // if
} //*** CClusterItem::WriteValue( LPCTSTR, CString& )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::WriteValue
//
// Routine Description:
// Write a REG_MULTI_SZ value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to write.
// pszKeyName [IN] Name of the key where the value resides.
// rlstrValue [IN] Value data.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CNTException( dwStatus )
// Any exceptions thrown by new.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::WriteValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, IN const CStringList & rlstrValue ) { DWORD dwStatus; LPWSTR pwszValue = NULL; LPWSTR pwszCurValue; POSITION posStr; DWORD cbValueLen; HKEY hkey; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( Hkey( ) != NULL );
// Get the size of the value.
posStr = rlstrValue.GetHeadPosition( ); cbValueLen = 0; while ( posStr != NULL ) { cbValueLen += ( rlstrValue.GetNext( posStr ).GetLength( ) + 1 ) * sizeof( TCHAR ); } // while: more items in the list
cbValueLen += 1 * sizeof( WCHAR ); // Extra NULL at the end.
// Allocate the value buffer.
pwszValue = new WCHAR[cbValueLen / sizeof( WCHAR )]; if ( pwszValue == NULL ) { ThrowStaticException( GetLastError( ) ); } // if
// Copy the strings to the values.
posStr = rlstrValue.GetHeadPosition( ); for ( pwszCurValue = pwszValue ; posStr != NULL ; pwszCurValue += lstrlenW( pwszCurValue ) + 1 ) { lstrcpyW( pwszCurValue, rlstrValue.GetNext( posStr ) ); } // for: each item in the list
pwszCurValue[0] = L'\0';
// Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_ALL_ACCESS, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { delete [] pwszValue; ThrowStaticException( dwStatus ); } // if: error opening the key
} // if: need to open a subkey
else { hkey = Hkey( ); } // else
// Write the value.
dwStatus = ClusterRegSetValue( hkey, pszValueName, REG_MULTI_SZ, (CONST BYTE *) pwszValue, cbValueLen - ( 1 * sizeof( WCHAR ) ) ); delete [] pwszValue; if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
if ( dwStatus != ERROR_SUCCESS ) { ThrowStaticException( dwStatus ); } // if
} //*** CClusterItem::WriteValue( LPCTSTR, CStringList& )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::WriteValue
//
// Routine Description:
// Write a REG_DWORD value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to write.
// pszKeyName [IN] Name of the key where the value resides.
// dwValue [IN] Value data.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CNTException( dwStatus )
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::WriteValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, IN DWORD dwValue ) { DWORD dwStatus; HKEY hkey; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( Hkey( ) != NULL );
// Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_ALL_ACCESS, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { ThrowStaticException( dwStatus ); } // if
} // if: need to open a subkey
else hkey = Hkey( );
// Write the value.
dwStatus = ClusterRegSetValue( hkey, pszValueName, REG_DWORD, (CONST BYTE *) &dwValue, sizeof( dwValue ) ); if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
if ( dwStatus != ERROR_SUCCESS ) { ThrowStaticException( dwStatus ); } // if
} //*** CClusterItem::WriteValue( LPCTSTR, DWORD )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::WriteValue
//
// Routine Description:
// Write a REG_BINARY value for this item if it hasn't changed.
//
// Arguments:
// pszValueName [IN] Name of the value to write.
// pszKeyName [IN] Name of the key where the value resides.
// pbValue [IN] Value data.
// cbValue [IN] Size of value data.
// ppbPrevValue [IN OUT] Previous value.
// cbPrevValue [IN] Size of the previous data.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CNTException( dwStatus )
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::WriteValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName, IN const LPBYTE pbValue, IN DWORD cbValue, IN OUT LPBYTE * ppbPrevValue, IN DWORD cbPrevValue ) { DWORD dwStatus; LPBYTE pbPrevValue = NULL; HKEY hkey; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( pbValue != NULL ); ASSERT( ppbPrevValue != NULL ); ASSERT( cbValue > 0 ); ASSERT( Hkey( ) != NULL );
// See if the data has changed.
if ( cbValue == cbPrevValue ) { DWORD ib;
for ( ib = 0 ; ib < cbValue ; ib++ ) { if ( pbValue[ ib ] != (*ppbPrevValue )[ ib ] ) { break; } // if
} // for: each byte in the value
if ( ib == cbValue ) { return; } // if
} // if: lengths are the same
// Allocate a new buffer for the previous data pointer.
pbPrevValue = new BYTE[ cbValue ]; if ( pbPrevValue == NULL ) { ThrowStaticException( GetLastError( ) ); } // if: error allocating previous data buffer
CopyMemory( pbPrevValue, pbValue, cbValue );
// Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_ALL_ACCESS, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { delete [] pbPrevValue; ThrowStaticException( dwStatus ); } // if: error opening the key
} // if: need to open a subkey
else { hkey = Hkey( ); } // else
// Write the value if it hasn't changed.
dwStatus = ClusterRegSetValue( hkey, pszValueName, REG_BINARY, pbValue, cbValue ); if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
if ( dwStatus == ERROR_SUCCESS ) { delete [] *ppbPrevValue; *ppbPrevValue = pbPrevValue; } // if: set was successful
else { delete [] pbPrevValue; ThrowStaticException( dwStatus ); } // else: error setting the value
} //*** CClusterItem::WriteValue( LPCTSTR, const LPBYTE )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::DeleteValue
//
// Routine Description:
// Delete the value for this item.
//
// Arguments:
// pszValueName [IN] Name of the value to delete.
// pszKeyName [IN] Name of the key where the value resides.
// rstrValue [IN] Value data.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CNTException( dwStatus )
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::DeleteValue( IN LPCTSTR pszValueName, IN LPCTSTR pszKeyName ) { DWORD dwStatus; HKEY hkey; CWaitCursor wc;
ASSERT( pszValueName != NULL ); ASSERT( Hkey( ) != NULL );
// Open a new key if needed.
if ( pszKeyName != NULL ) { dwStatus = ClusterRegOpenKey( Hkey( ), pszKeyName, KEY_ALL_ACCESS, &hkey ); if ( dwStatus != ERROR_SUCCESS ) { ThrowStaticException( dwStatus ); } // if
} // if: need to open a subkey
else { hkey = Hkey( ); } // else
// Delete the value.
dwStatus = ClusterRegDeleteValue( hkey, pszValueName ); if ( pszKeyName != NULL ) { ClusterRegCloseKey( hkey ); } // if
if ( dwStatus != ERROR_SUCCESS ) { ThrowStaticException( dwStatus ); } // if
} //*** CClusterItem::DeleteValue( LPCTSTR )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::BDifferent
//
// Routine Description:
// Compare two string lists.
//
// Arguments:
// rlstr1 [IN] First string list.
// rlstr2 [IN] Second string list.
//
// Return Value:
// TRUE Lists are different.
// FALSE Lists are the same.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CClusterItem::BDifferent( IN const CStringList & rlstr1, IN const CStringList & rlstr2 ) { BOOL bDifferent;
if ( rlstr1.GetCount( ) == rlstr2.GetCount( ) ) { POSITION posStr;
bDifferent = FALSE; posStr = rlstr1.GetHeadPosition( ); while ( posStr != NULL ) { if ( rlstr2.Find( rlstr1.GetNext( posStr ) ) == 0 ) { bDifferent = TRUE; break; } // if: string wasn't found
} // while: more items in the list
} // if: lists are the same size
else { bDifferent = TRUE; } // else
return bDifferent;
} //*** CClusterItem::BDifferent( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::BDifferentOrdered
//
// Routine Description:
// Compare two string lists.
//
// Arguments:
// rlstr1 [IN] First string list.
// rlstr2 [IN] Second string list.
//
// Return Value:
// TRUE Lists are different.
// FALSE Lists are the same.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CClusterItem::BDifferentOrdered( IN const CStringList & rlstr1, IN const CStringList & rlstr2 ) { BOOL bDifferent;
if ( rlstr1.GetCount( ) == rlstr2.GetCount( ) ) { POSITION posStr1; POSITION posStr2;
bDifferent = FALSE; posStr1 = rlstr1.GetHeadPosition( ); posStr2 = rlstr2.GetHeadPosition( ); while ( posStr1 != NULL ) { if ( posStr2 == NULL ) { bDifferent = TRUE; break; } // if: fewer strings in second list
if ( rlstr1.GetNext( posStr1 ) != rlstr2.GetNext( posStr2 ) ) { bDifferent = TRUE; break; } // if: strings are different
} // while: more items in the list
if ( posStr2 != NULL ) { bDifferent = TRUE; } // if
} // if: lists are the same size
else { bDifferent = TRUE; } // else
return bDifferent;
} //*** CClusterItem::BDifferentOrdered( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::BGetColumnData
//
// Routine Description:
// Returns a string with the column data for a
//
// Arguments:
// colid [IN] Column ID.
// rstrText [OUT] String in which to return the text for the column.
//
// Return Value:
// TRUE Column data returned.
// FALSE Column ID not recognized.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CClusterItem::BGetColumnData( IN COLID colid, OUT CString & rstrText ) { BOOL bSuccess;
switch ( colid ) { case IDS_COLTEXT_NAME: rstrText = StrName( ); bSuccess = TRUE; break; case IDS_COLTEXT_TYPE: rstrText = StrType( ); bSuccess = TRUE; break; case IDS_COLTEXT_DESCRIPTION: rstrText = StrDescription( ); bSuccess = TRUE; break; default: bSuccess = FALSE; rstrText = _T(""); break; } // switch: colid
return bSuccess;
} //*** CClusterItem::BGetColumnData( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::GetTreeName
//
// Routine Description:
// Returns a string to be used in a tree control.
//
// Arguments:
// rstrName [OUT] String in which to return the name.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
#ifdef _DISPLAY_STATE_TEXT_IN_TREE
void CClusterItem::GetTreeName( OUT CString & rstrName ) const { rstrName = StrName( );
} //*** CClusterItem::GetTreeName( )
#endif
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::PmenuPopup
//
// Routine Description:
// Returns a popup menu.
//
// Arguments:
// None.
//
// Return Value:
// pmenu A popup menu for the item.
//
//--
/////////////////////////////////////////////////////////////////////////////
CMenu * CClusterItem::PmenuPopup( void ) { CMenu * pmenu = NULL;
if ( IdmPopupMenu( ) != NULL ) { // Update the state of the item before we construct its menu.
UpdateState( );
// Load the menu.
pmenu = new CMenu; if ( pmenu == NULL ) { return NULL; } // if
if ( ! pmenu->LoadMenu( IdmPopupMenu( ) ) ) { delete pmenu; pmenu = NULL; } // if: error loading the menu
} // if: there is a menu for this item
return pmenu;
} //*** CClusterItem::PmenuPopup( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::AddTreeItem
//
// Routine Description:
// Add a tree item to the list item back pointer list.
//
// Arguments:
// pti [IN] Tree item to add.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::AddTreeItem( CTreeItem * pti ) { POSITION pos;
ASSERT_VALID( pti );
// Find the item in the list.
pos = LptiBackPointers( ).Find( pti );
// If it wasn't found, add it.
if ( pos == NULL ) { LptiBackPointers( ).AddTail( pti ); Trace( g_tagClusItemCreate, _T("AddTreeItem( ) - Adding tree item backptr from '%s' in '%s' - %d in list"), StrName( ), ( pti->PtiParent( ) == NULL ? _T("<ROOT>") : pti->PtiParent( )->StrName( ) ), LptiBackPointers( ).GetCount( ) ); } // if: item found in list
} //*** CClusterItem::AddTreeItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::AddListItem
//
// Routine Description:
// Add a list item to the list item back pointer list.
//
// Arguments:
// pli [IN] List item to add.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::AddListItem( CListItem * pli ) { POSITION pos;
ASSERT_VALID( pli );
// Find the item in the list.
pos = LpliBackPointers( ).Find( pli );
// If it wasn't found, add it.
if ( pos == NULL ) { LpliBackPointers( ).AddTail( pli ); Trace( g_tagClusItemCreate, _T("AddListItem( ) - Adding list item backptr from '%s' in '%s' - %d in list"), StrName( ), ( pli->PtiParent( ) == NULL ? _T("<ROOT>") : pli->PtiParent( )->StrName( ) ), LpliBackPointers( ).GetCount( ) ); } // if: item found in list
} //*** CClusterItem::AddListItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::RemoveTreeItem
//
// Routine Description:
// Remove a tree item from the tree item back pointer list.
//
// Arguments:
// pti [IN] Tree item to remove.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::RemoveTreeItem( CTreeItem * pti ) { POSITION pos;
ASSERT_VALID( pti );
// Find the item in the list.
pos = LptiBackPointers( ).Find( pti );
// If it was found, remove it.
if ( pos != NULL ) { LptiBackPointers( ).RemoveAt( pos ); Trace( g_tagClusItemDelete, _T("RemoveTreeItem( ) - Deleting tree item backptr from '%s' in '%s' - %d left"), StrName( ), ( pti->PtiParent( ) == NULL ? _T("<ROOT>") : pti->PtiParent( )->StrName( ) ), LptiBackPointers( ).GetCount( ) ); } // if: item found in list
} //*** CClusterItem::RemoveTreeItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::RemoveListItem
//
// Routine Description:
// Remove a list item from the list item back pointer list.
//
// Arguments:
// pli [IN] List item to remove.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::RemoveListItem( CListItem * pli ) { POSITION pos;
ASSERT_VALID( pli );
// Find the item in the list.
pos = LpliBackPointers( ).Find( pli );
// If it was found, remove it.
if ( pos != NULL ) { LpliBackPointers( ).RemoveAt( pos ); Trace( g_tagClusItemDelete, _T("RemoveListItem( ) - Deleting list item backptr from '%s' in '%s' - %d left"), StrName( ), ( pli->PtiParent( ) == NULL ? _T("<ROOT>") : pli->PtiParent( )->StrName( ) ), LpliBackPointers( ).GetCount( ) ); } // if: item found in list
} //*** CClusterItem::RemoveListItem( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CResource::CClusterItem
//
// Routine Description:
// Determines whether menu items corresponding to ID_FILE_RENAME
// should be enabled or not.
//
// Arguments:
// pCmdUI [IN OUT] Command routing object.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::OnUpdateRename( CCmdUI * pCmdUI ) { pCmdUI->Enable( BCanBeEdited( ) );
} //*** CClusterItem::OnUpdateRename( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::OnUpdateProperties
//
// Routine Description:
// Determines whether menu items corresponding to ID_FILE_PROPERTIES
// should be enabled or not.
//
// Arguments:
// pCmdUI [IN OUT] Command routing object.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::OnUpdateProperties( CCmdUI * pCmdUI ) { pCmdUI->Enable( FALSE );
} //*** CClusterItem::OnUpdateProperties( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::OnCmdProperties
//
// Routine Description:
// Processes the ID_FILE_PROPERTIES menu command.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterItem::OnCmdProperties( void ) { BDisplayProperties( );
} //*** CClusterItem::OnCmdProperties( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::BDisplayProperties
//
// Routine Description:
// Display properties for the object.
//
// Arguments:
// bReadOnly [IN] Don't allow edits to the object properties.
//
// Return Value:
// TRUE OK pressed.
// FALSE OK not pressed.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CClusterItem::BDisplayProperties( IN BOOL bReadOnly ) { AfxMessageBox( TEXT("Properties are not available."), MB_OK | MB_ICONWARNING ); return FALSE;
} //*** CClusterItem::BDisplayProperties( )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterItem::OnClusterNotify
//
// Routine Description:
// Handler for the WM_CAM_CLUSTER_NOTIFY message.
// Processes cluster notifications for this object.
//
// Arguments:
// pnotify [IN OUT] Object describing the notification.
//
// Return Value:
// Value returned from the application method.
//
//--
/////////////////////////////////////////////////////////////////////////////
LRESULT CClusterItem::OnClusterNotify( IN OUT CClusterNotify * pnotify ) { return 0;
} //*** CClusterItem::OnClusterNotify( )
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
// Global Functions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// DestructElements
//
// Routine Description:
// Destroys CClusterItem* elements.
//
// Arguments:
// pElements Array of pointers to elements to destruct.
// nCount Number of elements to destruct.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
extern void AFXAPI DestructElements( CClusterItem ** pElements, int nCount ) { ASSERT( nCount == 0 || AfxIsValidAddress( pElements, nCount * sizeof( CClusterItem * ) ) );
// call the destructor(s )
for ( ; nCount--; pElements++ ) { ASSERT_VALID( *pElements ); (*pElements)->Release( ); } // for: each item in the array
} //*** DestructElements( CClusterItem** )
/////////////////////////////////////////////////////////////////////////////
//++
//
// DeleteAllItemData
//
// Routine Description:
// Deletes all item data in a CList.
//
// Arguments:
// rlp [IN OUT] List whose data is to be deleted.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void DeleteAllItemData( IN OUT CClusterItemList & rlp ) { POSITION pos; CClusterItem * pci;
// Delete all the items in the Contained list.
pos = rlp.GetHeadPosition( ); while ( pos != NULL ) { pci = rlp.GetNext( pos ); ASSERT_VALID( pci ); // Trace( g_tagClusItemDelete, _T("DeleteAllItemData(rlpci ) - Deleting cluster item '%s'"), pci->StrName( ) );
pci->Delete( ); } // while: more items in the list
} //*** DeleteAllItemData( )
|