Click here to Skip to main content
15,881,882 members
Articles / Desktop Programming / MFC

Resource ID Organiser Add-In for Visual C++ 5.0/6.0/.NET

Rate me:
Please Sign up or sign in to vote.
4.98/5 (71 votes)
10 Jan 2005CPOL25 min read 530K   12.1K   201  
An application/add-in to organise and renumber resource symbol IDs
/************************************************************************
 *
 *                 Resource ID Organiser Core Library
 *
 * (c) Copyright 2000-2004 by Anna-Jayne Metcalfe (resorg@annasplace.me.uk)
 *                         All rights reserved.
 *
 ************************************************************************
 *                                                                       
 *  Filename    : ResourceSymbolManager.cpp
 *
 *  Description : CResourceSymbolManager - manager class for resource
 *                symbols
 *                
 *  Compiler    : Microsoft Visual C++ 6.0, Service Pack 3 or later
 *                Microsoft Visual C++ .NET 2003
 *                                                                       
 *  Target                                                               
 *  Environment : Windows 98/NT/2000/XP
 *
 *  NOTE:
 *
 *    This software is provided "as is" free for personal use. All
 *    title and copyrights in and to the software, including but not
 *    limited to any images, text, etc. incorporated into it, are
 *    owned by Anna-Jayne Metcalfe, except where acknowledged otherwise.
 *
 *    Your may freely to use this code in your own products, PROVIDED
 *    this notice is not removed or modified.
 *
 *
 *    Visit http://www.annasplace.me.uk/resorg for latest updates
 *
 ************************************************************************
 *
 *   MODIFICATION HISTORY:
 *
 *           This is a controlled document. See project configuration
 *           control tool for latest version and full version history.
 *
 *    $Archive: /Projects/AddIns/ResOrg/ResOrgCore/ResourceSymbolManager.cpp $
 *   $Revision: 45 $
 *       $Date: 20/12/04 13:12 $
 *     $Author: Anna $
 *
 *    $History: ResourceSymbolManager.cpp $
 * 
 * *****************  Version 45  *****************
 * User: Anna         Date: 20/12/04   Time: 13:12
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Initialised some class members
 * 
 * *****************  Version 44  *****************
 * User: Anna         Date: 29/08/04   Time: 21:13
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Corrections to CResourceSymbolManager::IsOutOfRange()
 * 
 * *****************  Version 43  *****************
 * User: Anna         Date: 29/08/04   Time: 10:46
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * CResourceSymbolManager::GetSymbolCount() now supports toolbars and
 * accelerators
 * 
 * *****************  Version 42  *****************
 * User: Anna         Date: 23/08/04   Time: 21:36
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Added support for out of range symbol detection
 * 
 * *****************  Version 41  *****************
 * User: Anna         Date: 11/07/04   Time: 16:15
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Added support for detection of out of range symbols
 * 
 * *****************  Version 40  *****************
 * User: Anna         Date: 11/05/04   Time: 0:22
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * By popular request...added support for "Fixed" symbols
 * 
 * *****************  Version 39  *****************
 * User: Anna         Date: 26/06/03   Time: 20:17
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * 1.  Added CResourceSymbolManager::GetBaseSymbolValue() to allow the
 * "Fix Conflicts" command in the Symbols Display to choose more
 * appropriate values.
 * 2.  Replaced hardcoded base symbol values with #defines
 * 
 * *****************  Version 38  *****************
 * User: Anna         Date: 23/06/03   Time: 16:41
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Improved handling of symbol base values
 * 
 * *****************  Version 37  *****************
 * User: Anna         Date: 15/04/03   Time: 20:50
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * 1.  Improved support for base values
 * 2.  Removed unnecessary file guards (#pragma once works well enough)
 * 
 * *****************  Version 36  *****************
 * User: Anna         Date: 3/04/03    Time: 13:31
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Added symbol base value attributes (not used yet)
 * 
 * *****************  Version 35  *****************
 * User: Anna         Date: 19/03/03   Time: 19:14
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * CResourceSymbolManager::Set() now calls
 * CResourceSymbol::RemoveConflict() if appropriate
 * 
 * *****************  Version 34  *****************
 * User: Anna         Date: 3/03/03    Time: 20:10
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Moved XML code to its own class (CResOrgXmlWriter)
 * 
 * *****************  Version 33  *****************
 * User: Anna         Date: 27/02/03   Time: 13:38
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Write "uid" attriutes for symbols and files so the XSL stylesheet can
 * identify objects uniquely
 * 
 * *****************  Version 32  *****************
 * User: Anna         Date: 19/02/03   Time: 19:20
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Started adding XML export and HTML reports
 * 
 * *****************  Version 31  *****************
 * User: Anna         Date: 15/02/03   Time: 20:50
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Changed big BOOLs into little bools
 * 
 * *****************  Version 30  *****************
 * User: Anna         Date: 19/01/03   Time: 17:24
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * CResourceSymbolManager::Serialize() now correctly calls
 * CResourceSymbol::SetUserData()
 * 
 * *****************  Version 29  *****************
 * User: Anna         Date: 3/01/03    Time: 7:38
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * CResourceSymbolManager doesn't need dynamic creation support
 * (DECLARE_DYNCREATE) - changed to runtime class info support
 * (DECLARE_DYNAMIC)
 * 
 * *****************  Version 28  *****************
 * User: Anna         Date: 2/01/03    Time: 0:09
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Mods for compatibility with multi-file symbol editing
 * 
 * *****************  Version 27  *****************
 * User: Anna         Date: 17/12/02   Time: 15:38
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * 1.  CResourceSymbolManager::Add() now sets the "User Data" field of a
 * CResourceSymbol object it creates
 * 2.  Minor correction to CResourceSymbolManager::GetNextFreeValue()
 * 
 * *****************  Version 26  *****************
 * User: Anna         Date: 25/11/02   Time: 15:19
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Changed website address in banner
 * 
 * *****************  Version 25  *****************
 * User: Anna         Date: 22/10/02   Time: 13:24
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Changed name/mail address (at last!)
 * 
 * *****************  Version 24  *****************
 * User: Andy         Date: 1/08/02    Time: 16:29
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Added CResourceSymbolManager::m_sPathName
 * 
 * *****************  Version 23  *****************
 * User: Andy         Date: 12/06/02   Time: 22:58
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Improved calculation of "Next Symbol" values
 * 
 * *****************  Version 22  *****************
 * User: Andy         Date: 7/06/02    Time: 17:04
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Renamed the ResOrgUtils module to ResOrgCore. Updated file banners
 * accordingly
 * 
 * *****************  Version 21  *****************
 * User: Andy         Date: 27/05/02   Time: 13:33
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Renamed CResourceSymbolBuffer as CResourceSymbolManager
 * 2.  Moved header file parsing/writing code to a new class
 * (CResourceSymbolFileBuffer)
 * 
 * *****************  Version 20  *****************
 * User: Andy         Date: 12/28/01   Time: 12:55a
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Changes to support new options and Wizard functionality
 * 
 * *****************  Version 19  *****************
 * User: Andy         Date: 11/07/01   Time: 1:21p
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Corrected the order of the "Next Symbol" defines
 * 2.  Changed the formatting of #defines to be a closer match to the
 * VC6.0 format (useful for file differencing)
 * 
 * *****************  Version 18  *****************
 * User: Andy         Date: 10/21/01   Time: 11:04p
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Corrected resource count in CResourceSymbolBuffer::GetSymbolCount() [it
 * was erroneously including controls]
 * 
 * *****************  Version 17  *****************
 * User: Andy         Date: 10/03/01   Time: 12:38p
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Added CResourceSymbolBuffer::AreNextSymbolValuesInUse() and
 * CalculateNextSymbolValues()
 * 
 * *****************  Version 16  *****************
 * User: Andy         Date: 16/08/01   Time: 7:01
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Bug fix in CResourceSymbolBuffer::UpdateNextSymbolValues()
 * 
 * *****************  Version 15  *****************
 * User: Andy         Date: 16/08/01   Time: 6:37
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Replaced some direct reads of member variables with access methods
 * 
 * *****************  Version 14  *****************
 * User: Andy         Date: 15/08/01   Time: 21:59
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Removed unnecessary #include of ReservedSymbolsDlg.h
 * 
 * *****************  Version 13  *****************
 * User: Andy         Date: 15/08/01   Time: 12:34
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Added extra metrics to CResourceSymbolCounts
 * 2.  CResourceSymbolBuffer attributes are now protected
 * 3.  Added access methods for "Next Symbol" values to
 * CResourceSymbolBuffer
 * 4.  CResourceSymbolBuffer::Serialize() now sets the "3D Controls" value
 * to 0 when loading a file in case it wasn't specified (otherwise it gets
 * converted to 1 when the file is saved)
 * 5.  CResourceSymbolBuffer::GetSymbolCount() now returns additional
 * metrics
 * CResourceSymbolBuffer::CalculateBaseValues()
 * 6.  The _APS_3D_CONTROLS define is now written to the file ONLY if the
 * value is set to 1 (true*
 * 
 * *****************  Version 12  *****************
 * User: Andy         Date: 2/07/01    Time: 22:05
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * CResourceSymbolBuffer::Renumber() is now updates "next symbol" values
 * correctly
 * 
 * *****************  Version 11  *****************
 * User: Andy         Date: 22/06/01   Time: 9:58
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * CResourceSymbolBuffer::Serialize() now marks itself as "not modified"
 * after loading a file
 * 
 * *****************  Version 10  *****************
 * User: Andy         Date: 4/05/01    Time: 22:34
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Renumber() no longer takes the "editable symbol" base value as a
 * parameter (it was never used anyway)
 * 
 * *****************  Version 9  *****************
 * User: Andy         Date: 23/04/01   Time: 21:17
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Consolidated Renumber() methods
 * 2.  Speeded up symbol loading
 * 
 * *****************  Version 8  *****************
 * User: Andy         Date: 21/04/01   Time: 7:29
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Added new exported methods
 * 
 * *****************  Version 7  *****************
 * User: Andy         Date: 2/04/01    Time: 17:32
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Check for name conflicts as well as value conflicts
 * 2.  Added IsUnique(Name/Value) methods
 * 3.  Added	GetUnusedName() metho
 * 
 * *****************  Version 6  *****************
 * User: Andy         Date: 27/03/01   Time: 15:39
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Added the capability to check resource symbol names for conflicts
 * 2.  Removed unused (and stubbed) Lookup() methods
 * 
 * *****************  Version 5  *****************
 * User: Andy         Date: 2/03/01    Time: 17:03
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Replaced literal strings with string table entries
 * 2.  Added a CResourceSymbolValuesMap object to manage symbol values
 * 3.  Removed CResourceSymbolBuffer::EditReservedSymbols() [this is now
 * the responsibility of CResOrgSymbolsDoc]
 * 
 * *****************  Version 4  *****************
 * User: Andy         Date: 19/02/01   Time: 8:30
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Added better tracking of values (alongside the existing method for
 * now..)
 * 
 * *****************  Version 3  *****************
 * User: Andy         Date: 17/02/01   Time: 6:54
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Added CResourceSymbolBuffer::GetDisplayedStatus() and GetSymbols()
 * 2.  Added support for read only symbols (the values of which saved in
 * hexadecimal)
 * 
 * *****************  Version 2  *****************
 * User: Andy         Date: 29/11/00   Time: 18:38
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 *  Added file banners
 *
 * $Nokeywords: $
 *
 ************************************************************************/


#include "StdAfx.h"
#include <math.h>

#include "ResOrgCore_Priv.h"

#include "ResourceSymbol.h"

#include "ResourceSymbolFileBuffer.h"

#include "ResourceSymbolManager.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



static UINT GetBaseRangeFromValue(UINT uValue)
{
	return (UINT)(1000 * ::floor( ((double)uValue) / 1000.0) );
}


/////////////////////////////////////////////////////////////////////////////
// CResourceSymbolManager

IMPLEMENT_DYNAMIC(CResourceSymbolManager, CResourceSymbolManager_BASE)

CResourceSymbolManager::CResourceSymbolManager(bool bAutoDelete /*= false*/)
{
	m_bAutoDelete					= bAutoDelete;			// Only set if created by CResourceSymbolConflictManager.

	m_sPathName						= _T("");
	m_sResourceFileName				= _T("");

	m_uBaseResourceValue			= SYM_RESOURCE_VALUE_DEFAULT;
	m_uBaseControlValue				= SYM_CONTROL_VALUE_DEFAULT;
	m_uBaseCommandValue				= SYM_COMMAND_VALUE_DEFAULT;
	
	m_uNextResourceValue			= SYM_RESOURCE_VALUE_DEFAULT;
	m_uNextControlValue				= SYM_CONTROL_VALUE_DEFAULT;
	m_uNextCommandValue				= SYM_COMMAND_VALUE_DEFAULT;
	m_uNextSymedValue				= m_uNextResourceValue + 100;

	m_b3dControls					= true;

	m_bModified						= false;
	m_nConflicts					= 0;
	m_nOutOfRangeSymbols			= 0;
	m_nProblemSymbols				= 0;
	m_bCheckForOutOfRangeSymbols	= Options.CheckForOutOfRangeSymbols();
}


CResourceSymbolManager::CResourceSymbolManager(const CResourceSymbolManager& src)
{
	m_bAutoDelete = false;

	*this = src;
}


CResourceSymbolManager::~CResourceSymbolManager(void)
{
	RemoveAll();
}


/////////////////////////////////////////////////////////////////////////////
// CResourceSymbolManager operators

void CResourceSymbolManager::operator=(const CResourceSymbolManager& src)
{
	RemoveAll();

	m_sPathName				= src.m_sPathName;
	m_sResourceFileName		= src.m_sResourceFileName;

	m_bModified				= src.m_bModified;
	m_nConflicts			= src.m_nConflicts;
	m_nOutOfRangeSymbols	= src.m_nOutOfRangeSymbols;
    m_nProblemSymbols		= src.m_nProblemSymbols;


	CResourceSymbolList listSymbols;
	src.GetSymbols(listSymbols);

	POSITION pos = listSymbols.GetHeadPosition();
	while (NULL != pos)
	{
		CResourceSymbol* pSymbol = listSymbols.GetNext(pos);
		if (NULL != pSymbol)
		{
			Add(pSymbol->GetName(),
				pSymbol->GetValue(),
				0,
				false);
		}
	}
	SortByValue();
	CountConflicts();

	m_b3dControls			= src.m_b3dControls;
	m_uNextResourceValue	= src.m_uNextResourceValue;
	m_uNextControlValue		= src.m_uNextControlValue;
	m_uNextSymedValue		= src.m_uNextSymedValue;
	m_uNextCommandValue		= src.m_uNextCommandValue;

	SetModifiedFlag(false);
}


/////////////////////////////////////////////////////////////////////////////
// CResourceSymbolManager Virtual Overrides

void CResourceSymbolManager::Serialize(CArchive& ar) 
{
	ASSERT_VALID(this);
	
	if (ar.IsLoading())
	{
		RemoveAll();

		CResourceSymbolFileBuffer buffer(&m_listSymbols);
		buffer.Serialize(ar);

		m_sPathName				= ar.GetFile()->GetFilePath();

		m_sResourceFileName		= buffer.GetResourceFileName();

		UINT uBaseResourceValue	= SYM_RESOURCE_VALUE_MIN;
		UINT uBaseControlValue	= SYM_CONTROL_VALUE_MIN;
		UINT uBaseCommandValue	= SYM_COMMAND_VALUE_MIN;
//		UINT uBaseResourceValue	= 0;
//		UINT uBaseControlValue	= 0;
//		UINT uBaseCommandValue	= 0;

		m_uNextResourceValue	= buffer.GetNextResourceValue();
		m_uNextCommandValue		= buffer.GetNextCommandValue();
		m_uNextControlValue		= buffer.GetNextControlValue();
		m_uNextSymedValue		= buffer.GetNextSymedValue();
		m_b3dControls			= (FALSE != buffer.Get3dControlsValue());

		POSITION pos = m_listSymbols.GetHeadPosition();

		while (NULL != pos)
		{
			CResourceSymbol* pSymbol = m_listSymbols.GetNext(pos);
			if (NULL != pSymbol)
			{
				m_mapNames.Add(pSymbol);
				m_mapValues.Add(pSymbol);

				pSymbol->SetUserData( (INT_PTR)this );

				UINT uValue = pSymbol->GetValue();
				
				switch (pSymbol->GetType())
				{
					case SYM_RESOURCE:
					default:
//						if ( (uValue < uBaseResourceValue) && (uValue >= SYM_RESOURCE_VALUE_MIN) )
//						if ( (uValue < uBaseResourceValue) || (0 == uBaseResourceValue) )
						if ( (SYM_RESOURCE_VALUE_MIN == uBaseResourceValue) ||
							 ( (uValue < uBaseResourceValue) && (uValue >= SYM_RESOURCE_VALUE_MIN) ) )
						{
							uBaseResourceValue = uValue;
						}
						break;

					case SYM_CONTROL:
//						if ( (uValue < uBaseControlValue) && (uValue >= SYM_CONTROL_VALUE_MIN) )
//						if ( (uValue < uBaseControlValue) || (0 == uBaseControlValue) )
						if ( (SYM_CONTROL_VALUE_MIN == uBaseControlValue) ||
							 ( (uValue < uBaseControlValue) && (uValue >= SYM_CONTROL_VALUE_MIN) ) )
						{
							uBaseControlValue = uValue;
						}
						break;

					case SYM_COMMAND:
//						if ( (uValue < uBaseCommandValue) && (uValue >= SYM_COMMAND_VALUE_MIN) )
//						if ( (uValue < uBaseCommandValue) || (0 == uBaseCommandValue) )
						if ( (SYM_COMMAND_VALUE_MIN == uBaseCommandValue) ||
							 ( (uValue < uBaseCommandValue) && (uValue >= SYM_COMMAND_VALUE_MIN) ) )
						{
							uBaseCommandValue = uValue;
						}
						break;
				}
			}
		}

		SetBaseResourceValue(uBaseResourceValue);
		SetBaseControlValue(uBaseControlValue);
		SetBaseCommandValue(uBaseCommandValue);

		SortByValue();

		CountConflicts();

		SetModifiedFlag(false);
	}
	else
	{
		CResourceSymbolFileBuffer buffer(&m_listSymbols);

		buffer.SetResourceFileName(m_sResourceFileName);
		buffer.SetNextResourceValue(m_uNextResourceValue);
		buffer.SetNextCommandValue(m_uNextCommandValue);
		buffer.SetNextControlValue(m_uNextControlValue);
		buffer.SetNextSymedValue(m_uNextSymedValue);
		buffer.Set3dControlsValue(m_b3dControls);

		buffer.Serialize(ar);
	}
}



/////////////////////////////////////////////////////////////////////////////
// CResourceSymbolManager Operations

CString CResourceSymbolManager::GetFileName(void) const
{
	CNGSplitPath split(m_sPathName);

	return split.GetFileName() + split.GetExtension();
}


bool CResourceSymbolManager::ReadSymbolFile(const CString& sPathName)
{
	ASSERT(!sPathName.IsEmpty() );

	if (!sPathName.IsEmpty() )
	{
		CStdioFile f;
		CFileException e;

		if (f.Open(	sPathName,
					CFile::modeRead |
					CFile::shareDenyWrite,
					&e) )
		{
			// File opened OK
			//
			// Now create an archive, and an empty text buffer
			CArchive ar(&f, CArchive::load);

			Serialize(ar);

			try
			{
				ar.Flush();
				ar.Close();
				f.Flush();
				f.Close();
			}
			catch (CException* e)
			{
				TCHAR szCause[255];
				e->GetErrorMessage(szCause, 255);
				CString sMsg;
				sMsg.Format( _T("Error closing project file\n\nDetails: %s\n"), szCause);

				TRACE1("%s\n", sMsg);
				AfxMessageBox(sMsg, MB_OK | MB_ICONSTOP);

				e->Delete();
			}

			return true;
		}
	}
	return false;
}


CString CResourceSymbolManager::GetDisplayedStatus(CResourceSymbol* pSymbol) const
{
	CString sStatus;

	if (!IsUnique( pSymbol->GetName() ) )
	{
		sStatus.LoadString(IDS_SYM_NAME_CONFLICT);
	}
	else if (!IsUnique( pSymbol->GetValue() ) )
	{
		CString sConflictList;

		CResourceSymbolList listSymbols;
		GetConflicts(pSymbol, listSymbols);

		POSITION pos = listSymbols.GetHeadPosition();
		while (pos != NULL)
		{
			CResourceSymbol* pConflictSymbol = listSymbols.GetNext(pos);
			if ( (NULL != pConflictSymbol) && (pConflictSymbol != pSymbol) )
			{
				sConflictList += pConflictSymbol->GetName() + _T(", ");
			}
		}
		sConflictList.TrimRight( _T(", ") );

		sStatus.Format(IDS_SYM_CONFLICTS, sConflictList);
	}
	else if (IsOutOfRange(pSymbol) )
	{
		sStatus.LoadString(IDS_SYM_OUT_OF_RANGE);
	}
	else if (pSymbol->IsModified())
	{
		sStatus.LoadString(IDS_SYM_MODIFIED);
	}
	else if (pSymbol->IsReadOnly())
	{
		sStatus.LoadString(IDS_SYM_READONLY);
	}
	else
	{
		sStatus.LoadString(IDS_SYM_OK);
	}
	return sStatus;
}


bool CResourceSymbolManager::CheckForOutOfRangeSymbols(bool bCheck)
{
	if (m_bCheckForOutOfRangeSymbols != bCheck)
	{
		m_bCheckForOutOfRangeSymbols = bCheck;

		CountConflicts();

		return true;
	}
	return false;
}


bool CResourceSymbolManager::IsOutOfRange(CResourceSymbol* pSymbol) const
{
	ASSERT(NULL != pSymbol);
	if (NULL != pSymbol)
	{
		return IsOutOfRange(pSymbol->GetType(), pSymbol->GetValue() );
	}
	return false;
}


bool CResourceSymbolManager::IsOutOfRange(int eSymbolType, UINT uValue) const
{
	if (!m_bCheckForOutOfRangeSymbols)
	{
		return false;
	}

	bool bValueOutOfRange = false;

	int nRange = GetSymbolCount();
	if (GetSymbolCount() < 100)
	{
		nRange = 100;
	}

	UINT uMaxResourceValue = GetBaseResourceValue() + nRange;
	UINT uMaxControlValue = GetBaseControlValue() + nRange;
	UINT uMaxCommandValue = GetBaseCommandValue() + nRange;

	switch (eSymbolType)
	{
		case SYM_RESOURCE:
		case SYM_BITMAP:
		case SYM_DIALOG:
		case SYM_MENU:
		case SYM_ICON:
		case SYM_TOOLBAR:
		case SYM_ACCELERATOR:
		case SYM_PROMPT:
		case SYM_STRING:
			bValueOutOfRange = ( (uValue < GetBaseResourceValue() ) || (uValue >= uMaxResourceValue) );
			break;

		case SYM_CONTROL:
			bValueOutOfRange = ( (uValue < GetBaseControlValue() ) || (uValue >= uMaxControlValue) );
			break;

		case SYM_COMMAND:
			bValueOutOfRange = ( (uValue < GetBaseCommandValue() ) || (uValue >= uMaxCommandValue) );
			break;

		default:
			ASSERT(FALSE);
			break;
	}
	return bValueOutOfRange;
}


UINT CResourceSymbolManager::GetBaseValue(int eSymbolType) const
{
	UINT uBaseValue = 0;
	switch (eSymbolType)
	{
		case SYM_RESOURCE:
		case SYM_BITMAP:
		case SYM_DIALOG:
		case SYM_MENU:
		case SYM_ICON:
		case SYM_TOOLBAR:
		case SYM_ACCELERATOR:
		case SYM_PROMPT:
		case SYM_STRING:
			uBaseValue = GetBaseResourceValue();
			break;

		case SYM_CONTROL:
			uBaseValue = GetBaseControlValue();
			break;

		case SYM_COMMAND:
			uBaseValue = GetBaseCommandValue();
			break;

		default:
			uBaseValue = GetBaseResourceValue();
			ASSERT(FALSE);
			break;
	}

	return uBaseValue;
}


bool CResourceSymbolManager::IsUnique(const CString& sName) const
{
	int nCount = m_mapNames.GetCount(sName);

	return (nCount <= 1);
}


bool CResourceSymbolManager::IsUnique(UINT uValue) const
{
	int nCount = m_mapValues.GetCount(uValue);

	return (nCount <= 1);
}


bool CResourceSymbolManager::IsInUse(const CString& sName) const
{
	int nCount = m_mapNames.GetCount(sName);

	return (nCount > 0);
}


bool CResourceSymbolManager::IsInUse(UINT uValue) const
{
	int nCount = m_mapValues.GetCount(uValue);

	return (nCount > 0);
}


int CResourceSymbolManager::GetSymbols(CResourceSymbolList& rlistSymbols) const
{
	rlistSymbols.RemoveAll();

	rlistSymbols.AddTail( (CResourceSymbolList*)&m_listSymbols);

	return rlistSymbols.GetCount();
}


int CResourceSymbolManager::GetSymbols(UINT uValue, CResourceSymbolList& rlistSymbols) const
{
	rlistSymbols.RemoveAll();

	m_mapValues.GetSymbols(uValue, rlistSymbols);

	return rlistSymbols.GetCount();
}


int CResourceSymbolManager::GetSymbols(const CString& sName, CResourceSymbolList& rlistSymbols) const
{
	rlistSymbols.RemoveAll();

	m_mapNames.GetSymbols(sName, rlistSymbols);

	return rlistSymbols.GetCount();
}



bool CResourceSymbolManager::Set(CResourceSymbol* pSymbol,
								 const CString& sName,
								 UINT uValue,
								 bool bReadOnly /*= false*/)
{
	if (uValue != pSymbol->GetValue() )
	{
		CSymbolConflictList& listSymbols = pSymbol->GetConflicts();

		CResourceSymbolList listSymbols2;
		POSITION pos = listSymbols.GetHeadPosition();
		while (NULL != pos)
		{
			CResourceSymbol* pConflict = listSymbols.GetNext(pos);
			if (pSymbol->GetValue() == pConflict->GetValue() )
			{
				pConflict->RemoveConflict(pSymbol);
				listSymbols2.AddTail(pConflict);
			}
		}
		
		pos = listSymbols2.GetHeadPosition();
		while (NULL != pos)
		{
			CResourceSymbol* pConflict = listSymbols2.GetNext(pos);
			pSymbol->RemoveConflict(pConflict);
		}
		m_mapValues.Remove(pSymbol);

		if (pSymbol->SetValue(uValue))
		{
			m_mapValues.Add(pSymbol);
		}
		m_bModified = true;
	}
	if (sName != pSymbol->GetName())
	{
		CSymbolConflictList& listSymbols = pSymbol->GetConflicts();

		CResourceSymbolList listSymbols2;
		POSITION pos = listSymbols.GetHeadPosition();
		while (NULL != pos)
		{
			CResourceSymbol* pConflict = listSymbols.GetNext(pos);
			if (pSymbol->GetName() == pConflict->GetName() )
			{
				pConflict->RemoveConflict(pSymbol);
				listSymbols2.AddTail(pConflict);
			}
		}
		
		pos = listSymbols2.GetHeadPosition();
		while (NULL != pos)
		{
			CResourceSymbol* pConflict = listSymbols2.GetNext(pos);
			pSymbol->RemoveConflict(pConflict);
		}
		m_mapNames.Remove(pSymbol);

		if (pSymbol->SetName(sName))
		{
			m_mapNames.Add(pSymbol);
		}
		m_bModified = true;
	}
	if (bReadOnly != pSymbol->IsReadOnly())
	{
		pSymbol->SetReadOnly(bReadOnly);
		m_bModified = true;
	}
	CountConflicts();

	return m_bModified;
}


CResourceSymbol* CResourceSymbolManager::Add(	const CString& sSymbolName,
												UINT uSymbolValue,
												int nLineNo,
												bool bUpdateMetrics /*= true*/)
{
	if (sSymbolName == _T("_APS_3D_CONTROLS") )
	{
		Set3dControlsValue( (uSymbolValue > 0) );
	}
	else if (sSymbolName == _T("_APS_NEXT_RESOURCE_VALUE") )
	{
		SetNextResourceValue(uSymbolValue);
	}
	else if (sSymbolName == _T("_APS_NEXT_CONTROL_VALUE") )
	{
		SetNextControlValue(uSymbolValue);
	}
	else if (sSymbolName == _T("_APS_NEXT_SYMED_VALUE") )
	{
		SetNextSymedValue(uSymbolValue);
	}
	else if (sSymbolName == _T("_APS_NEXT_COMMAND_VALUE") )
	{
		SetNextCommandValue(uSymbolValue);
	}
	else
	{
		CResourceSymbol* pSymbol = new CResourceSymbol;

		pSymbol->SetUserData( (INT_PTR)this );
		pSymbol->SetName(sSymbolName);
		pSymbol->SetValue(uSymbolValue);
		pSymbol->SetFileName(m_sPathName);
		pSymbol->SetLineNo(nLineNo);
		pSymbol->SetModifiedFlag(false);

		if (Add(pSymbol, bUpdateMetrics) )
		{
			return pSymbol;
		}
		delete pSymbol;
	}
	return NULL;
}


bool CResourceSymbolManager::Add(CResourceSymbol* pSymbol,
								 bool bUpdateMetrics /*= true*/)
{
	m_listSymbols.AddTail(pSymbol);

	m_mapNames.Add(pSymbol);
	m_mapValues.Add(pSymbol);

	if (bUpdateMetrics)
	{
		SortByValue();

		CountConflicts();
	}
	return true;
}


bool CResourceSymbolManager::Remove(CResourceSymbol* pSymbol,
								    bool bUpdateMetrics /*= true */)
{
	POSITION pos = m_listSymbols.Find(pSymbol);
	if (pos != NULL)
	{
		m_listSymbols.RemoveAt(pos);

		m_mapNames.Remove(pSymbol);
		m_mapValues.Remove(pSymbol);

		if (bUpdateMetrics)
		{
			CountConflicts();

			m_bModified = true;
		}
		return true;
	}
	return false;
}


void CResourceSymbolManager::RemoveAll(void)
{
	POSITION pos = m_listSymbols.GetHeadPosition();
	while (pos != NULL)
	{
		CResourceSymbol* pSymbol = m_listSymbols.GetNext(pos);
		if (pSymbol != NULL)
		{
			delete pSymbol;
		}
	}
	m_listSymbols.RemoveAll();
	m_mapNames.RemoveAll();
	m_mapValues.RemoveAll();

	m_nConflicts			= 0;
	m_nOutOfRangeSymbols	= 0;
	m_nProblemSymbols		= 0;

	m_bModified = true;
}


int CResourceSymbolManager::GetSymbolCount(CResourceSymbolCounts& rInfo) const
{
	UINT uMinResource	= 0;
	UINT uMaxResource	= 0;
	UINT uMinCommand	= 0;
	UINT uMaxCommand	= 0;

	POSITION pos = GetFirstSymbolPosition();
	while (pos != NULL)
	{
		CResourceSymbol* pSymbol = GetNextSymbol(pos);

		UINT uValue = pSymbol->GetValue();

		// First check the min/max values
		switch (pSymbol->GetType())
		{
			case SYM_COMMAND:
				uMinCommand = ( (uValue < uMinCommand) || (0 == uMinCommand) ) ? uValue : uMinCommand;
				uMaxCommand = (uValue > uMaxCommand) ? uValue : uMaxCommand;
				break;

			default:
				uMinResource = ( (uValue < uMinResource) || (0 == uMinResource) ) ? uValue : uMinResource;
				uMaxResource = (uValue > uMaxResource) ? uValue : uMaxResource;
				break;

		}
		// Now update the counts
		switch (pSymbol->GetType())
		{
			case SYM_RESOURCE:
			default:
				rInfo.m_nOtherResources++;
				rInfo.m_nResources++;
				break;

			case SYM_ACCELERATOR:
				rInfo.m_nAccelerators++;
				rInfo.m_nResources++;
				break;

			case SYM_BITMAP:
				rInfo.m_nBitmaps++;
				rInfo.m_nResources++;
				break;

			case SYM_DIALOG:
				rInfo.m_nDialogs++;
				rInfo.m_nResources++;
				break;

			case SYM_MENU:
				rInfo.m_nMenus++;
				rInfo.m_nResources++;
				break;

			case SYM_ICON:
				rInfo.m_nIcons++;
				rInfo.m_nResources++;
				break;

			case SYM_PROMPT:
				rInfo.m_nPrompts++;
				rInfo.m_nResources++;
				break;

			case SYM_STRING:
				rInfo.m_nStrings++;
				rInfo.m_nResources++;
				break;

			case SYM_TOOLBAR:
				rInfo.m_nToolbars++;
				rInfo.m_nResources++;
				break;

			case SYM_CONTROL:
				rInfo.m_nControls++;
				break;

			case SYM_COMMAND:
				rInfo.m_nCommands++;
				break;
		}
	}

	rInfo.m_uMinResource	= uMinResource;
	rInfo.m_uMaxResource	= uMaxResource;
	rInfo.m_uMinCommand		= uMinCommand;
	rInfo.m_uMaxCommand		= uMaxCommand;

	return rInfo.m_nResources +	rInfo.m_nControls + rInfo.m_nCommands;
}


bool CResourceSymbolManager::CalculateBaseValues(UINT& ruBaseResource,
												 UINT& ruBaseCommand,
												 UINT& ruBaseControl) const
{
	int nLowSum = 0;
	int nHighSum = 0;
	int nLowSymCount = 0;
	int nHighSymCount = 0;

	POSITION pos = GetFirstSymbolPosition();
	while (pos != NULL)
	{
		CResourceSymbol* pSymbol = GetNextSymbol(pos);

		UINT uValue = pSymbol->GetValue();
		if (uValue >= 32767)	// high range
		{
			nHighSum += uValue;
			nHighSymCount++;
		}
		else
		{
			nLowSum += uValue;
			nLowSymCount++;
		}
	}
	if (nLowSum > 0)
	{
		int nLowAvg = (nLowSum / nLowSymCount);

		ruBaseResource	= ::GetBaseRangeFromValue(nLowAvg);
	}
	if (nHighSum > 0)
	{
		int nHighAvg = (nHighSum / nHighSymCount);

		ruBaseCommand	= ::GetBaseRangeFromValue(nHighAvg);
	}
	bool bResult = ((nLowSum > 0) && (nHighSum > 0));

	// Validate against defined ranges, just to be sure....
	// This is friggy code, but it'll do for now
	if (ruBaseResource < SYM_RESOURCE_VALUE_MIN)
	{
		ruBaseResource = SYM_RESOURCE_VALUE_MIN;
	}
	else if (ruBaseResource > SYM_RESOURCE_VALUE_MAX)
	{
		ruBaseResource	= ::GetBaseRangeFromValue(SYM_RESOURCE_VALUE_MAX);
	}

	if (ruBaseCommand < SYM_COMMAND_VALUE_MIN)
	{
		ruBaseCommand	= SYM_COMMAND_VALUE_MIN;
	}
	else if (ruBaseCommand > SYM_COMMAND_VALUE_MAX)
	{
		ruBaseCommand	= ::GetBaseRangeFromValue(SYM_COMMAND_VALUE_MAX);
	}

	CResourceSymbolCounts Info;
	GetSymbolCount(Info);

	int nControlOffset	= (int)(100 * ::ceil( (double)Info.m_nResources / 100.0) );

	ruBaseControl	= ruBaseResource + nControlOffset;

	return bResult;
}


bool CResourceSymbolManager::Renumber(	CResourceSymbolList* plistSymbols,
										UINT uBaseResource,
										UINT uBaseCommand,
										UINT uBaseControl,
										bool bIgnoreFixedStatus /*= false*/,
										bool bSortByName /*= true*/)
{
	bool bResult = false;

	SetBaseResourceValue(uBaseResource);
	SetBaseControlValue(uBaseControl);
	SetBaseCommandValue(uBaseCommand);

	UINT uNextResourceValue		= uBaseResource;
	UINT uNextControlValue		= uBaseControl;
	UINT uNextCommandValue		= uBaseCommand;

	if (bSortByName)
	{
		plistSymbols->SortByName();
	}
	else
	{
		plistSymbols->SortByValue();
	}

	// First, remove all values from the values map
	// so that we can reuse their previous values...
	POSITION pos = plistSymbols->GetHeadPosition();

	while (pos != NULL)
	{
		CResourceSymbol* pSymbol = plistSymbols->GetNext(pos);

		if ( (NULL != pSymbol) && !pSymbol->IsReadOnly() &&
			(bIgnoreFixedStatus || !Options.IsFixedSymbol(pSymbol->GetName() ) ) )
		{
			m_mapValues.Remove(pSymbol);
		}
	}

	// Now renumber them
	pos = plistSymbols->GetHeadPosition();
	while (pos != NULL)
	{
		CResourceSymbol* pSymbol = plistSymbols->GetNext(pos);
		if ( (NULL != pSymbol) && !pSymbol->IsReadOnly() &&
			(bIgnoreFixedStatus || !Options.IsFixedSymbol(pSymbol->GetName() ) ) )
		{
			switch (pSymbol->GetType())
			{
				case SYM_RESOURCE:
				case SYM_DIALOG:
				case SYM_MENU:
				case SYM_STRING:
				case SYM_PROMPT:
				case SYM_BITMAP:
				case SYM_ICON:
					uNextResourceValue = GetNextFreeValue(uNextResourceValue);
					if (uNextResourceValue != pSymbol->GetValue() )
					{
						Set(pSymbol,
							pSymbol->GetName(),
							uNextResourceValue++);

						bResult = true;
					}
					else
					{
						m_mapValues.Add(pSymbol);
					}
					break;

				case SYM_COMMAND:
					uNextCommandValue = GetNextFreeValue(uNextCommandValue);
					if (uNextCommandValue != pSymbol->GetValue() )
					{
						Set(pSymbol,
							pSymbol->GetName(),
							uNextCommandValue++);

						bResult = true;
					}
					else
					{
						m_mapValues.Add(pSymbol);
					}
					break;

				case SYM_CONTROL:
					uNextControlValue = GetNextFreeValue(uNextControlValue);
					if (uNextControlValue != pSymbol->GetValue() )
					{
						Set(pSymbol,
							pSymbol->GetName(),
							uNextControlValue++);

						bResult = true;
					}
					else
					{
						m_mapValues.Add(pSymbol);
					}
					break;

				default:
					ASSERT(false);
					break;
			}
		}
	}
	if (bResult)
	{
		UpdateNextSymbolValues();
	}
	return bResult;
}


/// Renumber all symbols
///
bool CResourceSymbolManager::Renumber(	UINT uBaseResource,
										UINT uBaseCommand,
										UINT uBaseControl,
										bool bIgnoreFixedStatus /*= false*/,
										bool bSortByName /*= true*/)
{
	return Renumber(&m_listSymbols,
					uBaseResource,
					uBaseCommand,
					uBaseControl,
					bIgnoreFixedStatus,
					bSortByName);
}


bool CResourceSymbolManager::UpdateNextSymbolValues(void)
{
	bool bResult = false;

	UINT uNextResourceValue	= 0;
	UINT uNextCommandValue	= 0;
	UINT uNextControlValue	= 0;
	UINT uNextSymedValue	= 0;

	CalculateNextSymbolValues(	uNextResourceValue,
								uNextControlValue,
								uNextCommandValue,
								uNextSymedValue);

	bResult = SetNextResourceValue(uNextResourceValue);

	if (!SetNextCommandValue(uNextCommandValue) )
	{
		bResult = false;
	}
	if (!SetNextControlValue(uNextControlValue) )
	{
		bResult = false;
	}
	if (!SetNextSymedValue(uNextSymedValue))
	{
		bResult = false;
	}

	return bResult;
}


bool CResourceSymbolManager::AreNextSymbolValuesInUse(void) const
{
	bool bResult = false;

	bool bNextResourceIDUsed	= IsInUse(m_uNextResourceValue);
	bool bNextControlIDUsed		= IsInUse(m_uNextControlValue);
	bool bNextCommandIDUsed		= IsInUse(m_uNextCommandValue);
	bool bNextSymedIDUsed		= IsInUse(m_uNextSymedValue);

	bResult = bNextResourceIDUsed ||
				bNextControlIDUsed ||
				bNextCommandIDUsed ||
				bNextSymedIDUsed;

	return bResult;
}


bool CResourceSymbolManager::FixNextSymbolValues(void)
{
	bool bResult = false;

	if (AreNextSymbolValuesInUse() )
	{
		UINT uNextResourceValue = 0;
		UINT uNextControlValue = 0;
		UINT uNextCommandValue = 0;
		UINT uNextSymedValue = 0;

		CalculateNextSymbolValues(	uNextResourceValue,
									uNextControlValue,
									uNextCommandValue,
									uNextSymedValue);

		if ( IsInUse(m_uNextResourceValue) )
		{
			bResult = SetNextResourceValue(uNextResourceValue);
		}
		if ( IsInUse(m_uNextControlValue) )
		{
			bResult = SetNextControlValue(uNextControlValue);
		}
		if ( IsInUse(m_uNextCommandValue) )
		{
			bResult = SetNextCommandValue(uNextCommandValue);
		}
		if ( IsInUse(m_uNextSymedValue) )
		{
			bResult = SetNextSymedValue(uNextSymedValue);
		}
		ASSERT( !AreNextSymbolValuesInUse() );

	}
	return bResult;
}


bool CResourceSymbolManager::CalculateNextSymbolValues(	UINT& ruNextResourceValue,
														UINT& ruNextControlValue,
														UINT& ruNextCommandValue,
														UINT& ruNextSymedValue)
{
	bool bResult = false;

	POSITION pos = GetFirstSymbolPosition();

	UINT uNextResourceValue	= 0;
	UINT uNextCommandValue	= 0;
	UINT uNextControlValue	= 0;

	while (pos != NULL)
	{
		CResourceSymbol* pSymbol = GetNextSymbol(pos);
		if (NULL != pSymbol)
		{
			switch (pSymbol->GetType())
			{
				case SYM_RESOURCE:
				case SYM_DIALOG:
				case SYM_MENU:
				case SYM_STRING:
				case SYM_PROMPT:
				case SYM_BITMAP:
				case SYM_ICON:
					if (pSymbol->GetValue() > uNextResourceValue)
					{
						uNextResourceValue = GetNextFreeValue(pSymbol->GetValue());
					}
					break;

				case SYM_COMMAND:
					if (pSymbol->GetValue() > uNextCommandValue)
					{
						uNextCommandValue = GetNextFreeValue(pSymbol->GetValue());
					}
					break;

				case SYM_CONTROL:
					if (pSymbol->GetValue() > uNextControlValue)
					{
						uNextControlValue = GetNextFreeValue(pSymbol->GetValue());
					}
					break;

				default:
					break;
			}
		}
	}

	// If we didn't calculate a new value for any of the constants,
	// just make sure there are no conflicts
	if (0 == uNextResourceValue)
	{
		uNextResourceValue = GetNextFreeValue(ruNextResourceValue);
	}
	if (0 == uNextControlValue)
	{
		uNextControlValue = GetNextFreeValue(ruNextControlValue);
	}
	if (0 == uNextCommandValue)
	{
		uNextCommandValue = GetNextFreeValue(ruNextCommandValue);
	}

	UINT uNextSymedValue = GetNextFreeValue(max(	uNextResourceValue + 100,
													uNextControlValue + 100) );	// Fairly arbitrary, but it should be OK

	// Finally - see what's changed
	if (ruNextResourceValue != uNextResourceValue)
	{
		ruNextResourceValue = uNextResourceValue;
		bResult = true;
	}

	if (ruNextControlValue != uNextControlValue)
	{
		ruNextControlValue = uNextControlValue;
		bResult = true;
	}

	if (ruNextCommandValue != uNextCommandValue)
	{
		ruNextCommandValue = uNextCommandValue;
		bResult = true;
	}

	if ( (uNextSymedValue > 0) && (ruNextSymedValue != uNextSymedValue) )
	{
		ruNextSymedValue = uNextSymedValue;
		bResult = true;
	}


	return bResult;
}


UINT CResourceSymbolManager::GetBaseSymbolValue(int eSymbolType) const
{
	UINT uBaseValue = 0;
	switch (eSymbolType)
	{
		case SYM_RESOURCE:
		default:
			uBaseValue = GetBaseResourceValue();
			break;

		case SYM_CONTROL:
			uBaseValue = GetBaseControlValue();
			break;

		case SYM_COMMAND:
			uBaseValue = GetBaseCommandValue();
			break;

	}
	ASSERT(uBaseValue > 0);

	return uBaseValue;
}


bool CResourceSymbolManager::SetBaseResourceValue(UINT uValue)
{
	if ( (m_uBaseResourceValue != uValue) && (uValue >= SYM_RESOURCE_VALUE_MIN) && (uValue <= SYM_RESOURCE_VALUE_MAX) )
	{
		m_uBaseResourceValue = uValue;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::SetBaseControlValue(UINT uValue)
{
	if ( (m_uBaseControlValue != uValue) && (uValue >= SYM_CONTROL_VALUE_MIN) && (uValue <= SYM_CONTROL_VALUE_MAX) )
	{
		m_uBaseControlValue = uValue;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::SetBaseCommandValue(UINT uValue)
{
	if ( (m_uBaseCommandValue != uValue) && (uValue >= SYM_COMMAND_VALUE_MIN) && (uValue <= SYM_COMMAND_VALUE_MAX) )
	{
		m_uBaseCommandValue = uValue;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::Set3dControlsValue(bool b3dControls)
{
	if (m_b3dControls != b3dControls)
	{
		m_b3dControls	= b3dControls;

		m_bModified		= true;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::SetNextResourceValue(UINT uValue)
{
	if ( (uValue > 0) && (uValue != IDC_STATIC) && (uValue != m_uNextResourceValue) )
	{
		m_uNextResourceValue = uValue;

		m_bModified			= true;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::SetNextCommandValue(UINT uValue)
{
	if ( (uValue > 0) && (uValue != IDC_STATIC) && (uValue != m_uNextCommandValue) )
	{
		m_uNextCommandValue = uValue;

		m_bModified			= true;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::SetNextControlValue(UINT uValue)
{
	if ( (uValue > 0) && (uValue != IDC_STATIC) && (uValue != m_uNextControlValue) )
	{
		m_uNextControlValue = uValue;

		m_bModified			= true;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::SetNextSymedValue(UINT uValue)
{
	if ( (uValue > 0) && (uValue != IDC_STATIC) && (uValue != m_uNextSymedValue) )
	{
		m_uNextSymedValue	= uValue;

		m_bModified			= true;

		return true;
	}
	return false;
}


bool CResourceSymbolManager::SetModifiedFlag(bool bModified)
{
	m_bModified = bModified;

	if (!m_bModified)
	{
		POSITION pos = GetFirstSymbolPosition();

		while (pos != NULL)
		{
			CResourceSymbol* pSymbol = GetNextSymbol(pos);
			if (NULL != pSymbol)
			{
				pSymbol->SetModifiedFlag(false);
			}
		}
	}
	return true;
}


CString CResourceSymbolManager::GetUnusedName(int eType) const
{
	CString sName;

	CString sBaseName = SymbolTypes.GetTypePrefix(eType) +
						_T("NEW_SYMBOL");

	int n = 1;
	do
	{
		if (n <= 1)
		{
			sName = sBaseName;
		}
		else
		{
			sName.Format(sBaseName + _T("%d"), n);
		}
		n++;
	} while ( IsInUse(sName) );

	return sName;
}


UINT CResourceSymbolManager::GetNextFreeValue(UINT uValue) const
{
	while (IsInUse(uValue) )
	{
		if ( ((unsigned short)IDC_STATIC) == uValue)
		{
			ASSERT(false);
			break;
		}
		uValue++;
	}
	return uValue;
}


/////////////////////////////////////////////////////////////////////////////
// Implementation


void CResourceSymbolManager::CountConflicts(void)
{
	m_nConflicts			= 0;
	m_nOutOfRangeSymbols	= 0;
	m_nProblemSymbols		= 0;

	POSITION pos = m_listSymbols.GetHeadPosition();
	while (pos != NULL)
	{
		CResourceSymbol* pSymbol = m_listSymbols.GetNext(pos);

		if (NULL != pSymbol)
		{
			if (!IsUnique( pSymbol->GetName() ) || !IsUnique( pSymbol->GetValue() ) )
			{
				m_nConflicts++;
				m_nProblemSymbols++;

				if (IsOutOfRange(pSymbol) )
				{
					m_nOutOfRangeSymbols++;
				}
			}
			else if (IsOutOfRange(pSymbol) )
			{
				m_nOutOfRangeSymbols++;
				m_nProblemSymbols++;
			}
		}
	}
}


int CResourceSymbolManager::GetConflicts(CResourceSymbolList& rlistConflicts) const
{
	rlistConflicts.RemoveAll();

	POSITION pos = GetFirstSymbolPosition();
	while (NULL != pos)
	{
		CResourceSymbol* pSymbol = GetNextSymbol(pos);

		if (NULL != pSymbol)
		{
			if (!IsUnique( pSymbol->GetValue() ) )
			{
				rlistConflicts.AddTail(pSymbol);
			}
		}
	}
	return rlistConflicts.GetCount();
}


int CResourceSymbolManager::GetOutOfRangeSymbols(CResourceSymbolList& rlistSymbols) const
{
	rlistSymbols.RemoveAll();

	POSITION pos = GetFirstSymbolPosition();
	while (NULL != pos)
	{
		CResourceSymbol* pSymbol = GetNextSymbol(pos);

		if (NULL != pSymbol)
		{
			if (IsOutOfRange(pSymbol) )
			{
				rlistSymbols.AddTail(pSymbol);
			}
		}
	}
	return rlistSymbols.GetCount();
}


int CResourceSymbolManager::GetConflicts(CResourceSymbol* pSymbol,
										 CResourceSymbolList& rlistConflicts) const
{
	rlistConflicts.RemoveAll();

	rlistConflicts.AddTail( (CResourceSymbolList*)&pSymbol->GetConflicts() );

	return rlistConflicts.GetCount();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder Riverblade Limited
United Kingdom United Kingdom
I haven't always written software for a living. When I graduated from Surrey University in 1989, it was with an Electronic Engineering degree, but unfortunately that never really gave me the opportunity to do anything particularly interesting (with the possible exception of designing Darth Vader's Codpiece * for the UK Army in 1990).
    * Also known as the Standard Army Bootswitch. But that's another story...
Since the opportunity arose to lead a software team developing C++ software for Avionic Test Systems in 1996, I've not looked back. More recently I've been involved in the development of subsea acoustic navigation systems, digital TV broadcast systems, port security/tracking systems, and most recently software development tools with my own company, Riverblade Ltd.

One of my personal specialities is IDE plug-in development. ResOrg was my first attempt at a plug-in, but my day to day work is with Visual Lint, an interactive code analysis tool environment with works within the Visual Studio and Eclipse IDEs or on build servers.

I love lots of things, but particularly music, photography and anything connected with history or engineering. I despise ignorant, intolerant and obstructive people - and it shows...I can be a bolshy cow if you wind me up the wrong way...Laugh | :laugh:

I'm currently based 15 minutes walk from the beach in Bournemouth on the south coast of England. Since I moved here I've grown to love the place - even if it is full of grockles in Summer!

Comments and Discussions