Click here to Skip to main content
15,881,172 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 529.9K   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    : ResourceSymbol.cpp
 *
 *  Description : CResourceSymbol - class to represent a single resource symbol
 *                
 *  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/ResourceSymbol.cpp $
 *   $Revision: 19 $
 *       $Date: 23/08/04 21:39 $
 *     $Author: Anna $
 *
 *    $History: ResourceSymbol.cpp $
 * 
 * *****************  Version 19  *****************
 * User: Anna         Date: 23/08/04   Time: 21:39
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Added support for SYM_TOOLBAR (IDT_xxx) and SYM_ACCELERATOR (IDK_xxx)
 * symbols
 * 
 * *****************  Version 18  *****************
 * User: Anna         Date: 11/07/04   Time: 16:06
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Improved code documentation
 * 
 * *****************  Version 17  *****************
 * User: Anna         Date: 15/04/03   Time: 20:36
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Corrected code documentation comments
 * 
 * *****************  Version 16  *****************
 * User: Anna         Date: 19/03/03   Time: 18:43
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Undid some blondeness in CResourceSymbol::SetModifiedFlag()
 * 
 * *****************  Version 15  *****************
 * User: Anna         Date: 3/03/03    Time: 20:10
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Moved XML code to its own class (CResOrgXmlWriter)
 * 
 * *****************  Version 14  *****************
 * 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 13  *****************
 * User: Anna         Date: 25/02/03   Time: 21:26
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * CResourceSymbol::AddConflict() now checks to ensure the symbol isn't
 * already listed before adding it
 * 
 * *****************  Version 12  *****************
 * User: Anna         Date: 19/02/03   Time: 19:20
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Started adding XML export and HTML reports
 * 
 * *****************  Version 11  *****************
 * User: Anna         Date: 15/02/03   Time: 20:52
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Changed big BOOLs into little bools
 * 
 * *****************  Version 10  *****************
 * User: Anna         Date: 3/12/02    Time: 20:18
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Added CResourceSymbol::m_nUserData
 * 
 * *****************  Version 9  *****************
 * User: Anna         Date: 25/11/02   Time: 15:20
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Changed website address in banner
 * 
 * *****************  Version 8  *****************
 * User: Anna         Date: 22/10/02   Time: 13:24
 * Updated in $/Projects/AddIns/ResOrg/ResOrgCore
 * Changed name/mail address (at last!)
 * 
 * *****************  Version 7  *****************
 * 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 6  *****************
 * User: Andy         Date: 27/05/02   Time: 17:10
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Revised the way conflicts are stored to remove a two-way code
 * dependency which caused big problems in Visual C++ 7.0
 * 
 * *****************  Version 5  *****************
 * User: Andy         Date: 12/27/01   Time: 10:48p
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Added "Original Value" attribute
 * 
 * *****************  Version 4  *****************
 * User: Andy         Date: 2/04/01    Time: 17:03
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * The default constructor now has optional parameters for the Name, Value
 * and Read-Only status of the symbol
 * 
 *****************  Version 3  *****************
 * User: Andy            Date: 27/03/01  Time:  15:37
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * Added CResourceSymbol::IsValidName()
 *
 *****************  Version 2  *****************
 * User: Andy            Date: 17/02/01  Time:   6:49
 * Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
 * 1.  Moved resource type identification to a separate class
 * 2.  Added SetReadOnly(), IsReadOnly() and GetConflicts()
 *
 ******************  Version 1  *****************
 * User: Andy            Date: 12/11/00  Time:  21:36
 * Created in $/Projects/AddIns/ResOrg/ResOrgUtils
 *
 * $Nokeywords: $
 *
 ************************************************************************/


#include "StdAfx.h"
#include "ResOrgCore_Priv.h"

#include "ResourceSymbol.h"


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



/////////////////////////////////////////////////////////////////////////////
// CResourceSymbol


IMPLEMENT_DYNCREATE(CResourceSymbol, CResourceSymbol_BASE)


/// CResourceSymbol constructor.
///
/// \param	sName		The name of the symbol.
/// \param	uValue		The value of the symbol.
/// \param	bReadOnly	true if the symbol should be read-only; false otherwise.
///						Read-only symbols are saved in hexadecimal, and the resource editor <b>hates</b> them, so be careful!
///
CResourceSymbol::CResourceSymbol(const CString& sName /*= _T("")*/,
								 UINT uValue /*= 0*/,
								 bool bReadOnly /*= false*/)
{
	m_sName				= sName;
	m_uValue			= uValue;
	m_uOriginalValue	= 0;
	m_sFileName			= _T("");
	m_nLineNo			= 0;

	m_bModified			= false;
	m_bReadOnly			= bReadOnly;

	m_nUserData			= 0;
}


CResourceSymbol::~CResourceSymbol(void)
{
}


/////////////////////////////////////////////////////////////////////////////
// Virtual Overrides
// (none)


/////////////////////////////////////////////////////////////////////////////
// Operations

/// Return the type of the symbol, in enumerated form
///
/// The following symbol types are available:
///
///		- SYM_RESOURCE (IDx_xxx)
///		- SYM_BITMAP (IDB_xxx)
///		- SYM_CONTROL (IDC_xxx)
///		- SYM_DIALOG (IDD_xxx)
///		- SYM_MENU (IDM_xxx)
///		- SYM_ICON (IDI_xxx)
///		- SYM_PROMPT (IDP_xxx)
///		- SYM_STRING (IDS_xxx)
///		- SYM_COMMAND (ID_xxx)
///		- SYM_TOOLBAR (IDT_xxx)
///		- SYM_ACCELERATOR (IDK_xxx)
///
/// \return				The enumerated type of the symbol
///
int CResourceSymbol::GetType(void) const
{
	return SymbolTypes.GetType(m_sName);
}


/// Return the type of the symbol, in string form.
///
/// This method is intended for display purposes and hence the names should
/// ideally be loaded from a string table entry.
///
/// \return				The type of the symbol, in string form.
///
CString CResourceSymbol::GetTypeName(void) const
{
	return SymbolTypes.GetTypeName( GetType() );
}


/// Determine whether the given symbol name is valid.
///
///	The following rules are applied in validating the name:
///
///		- The name must not be blank (obviously...)
///		- The first character must be alphabetic
///		- The remainder of the name must contain only alphanumeric characters
///		  or underscores.
///		- Leading and trailing spaces are \b not permitted.
///
/// \param				The name to be validated
/// \return				true if the symbol name is valid; false otherwise.
///
bool CResourceSymbol::IsValidName(const CString& sName)
{
	bool  bValid = false;

	if (!sName.IsEmpty())
	{
		if (::isalpha(sName[0]) )
		{
			for (int n = 0; n < sName.GetLength(); n++)
			{
				TCHAR ch = sName[n];
				if ( _T('_') == ch)
				{
					bValid = true;
					continue;		// Underscores are OK
				}
				if (::isalnum(ch) )
				{
					bValid = true;
					continue;
				}
				// If we get here, the symbol name isn't valid
				bValid = false;
				break;
			}
		}
	}
	return bValid;
}


/// Get the pathname of the resource symbol file in which this symbol is defined.
///
/// \return				The contents of m_sFileName, which holds the pathname of the resource symbol file.
///
CString CResourceSymbol::GetFileName(void) const
{
	return m_sFileName;
}
	

/// Set the pathname of the resource symbol file in which this symbol is defined.
///
/// \param sFileName	The pathname of the resource symbol file
/// \return				true if m_sFileName was changed, false otherwise
///
/// Note that changing the line no. or pathname of a symbol does \b not
/// mark it as modified. This is by design.
///
bool CResourceSymbol::SetFileName(const CString& sFileName)
{
	if (m_sFileName != sFileName)
	{
		m_sFileName = sFileName;

		return true;
	}
	return false;
}


/// Set the line number of this symbol in its resource symbol file
///
/// \param nLineNo		The line number of the symbol
/// \return				true if m_nLineNo was changed, false otherwise
///
/// Note that changing the line no or pathname of a symbol does \b not
/// mark it as modified. This is by design.
///
bool CResourceSymbol::SetLineNo(int nLineNo)
{
	if (m_nLineNo != nLineNo)
	{
		m_nLineNo = nLineNo;

		return true;
	}
	return false;
}


/// Return the name of this symbol
///
/// \return			The name of the symbol
///
CString	CResourceSymbol::GetName(void) const
{
	return m_sName;
}


/// Set the name of this symbol
///
/// \param sName	The new value of the symbol
/// \return			true if m_sName was changed, false otherwise
///
bool CResourceSymbol::SetName(const CString& sName)
{
	if (m_sName != sName)
	{
		m_sName = sName;

		SetModifiedFlag();

		return true;
	}
	return false;
}


/// Get the value of this symbol
///
/// \return			The contents of m_uValue, which holds the value of the symbol.
///
UINT CResourceSymbol::GetValue(void) const
{
	return m_uValue;
}


/// Set the value of this symbol
///
/// \param uValue	The new value of the symbol.
/// \return			true if m_uValue was changed, false otherwise.
///
bool CResourceSymbol::SetValue(UINT uValue)
{
	if (m_uValue != uValue)
	{
		// If the sybol wasn't modified before, save the original value before changing it
		if (!m_bModified)
		{
			m_uOriginalValue = m_uValue;
		}
		m_uValue = uValue;

		SetModifiedFlag();

		return true;
	}
	return false;
}


/// Get the previous value of this symbol. This operation is only valid if the symbol has been modified.
///
/// \return			The contents of m_uOriginalValue, which holds the previous value of the symbol.
///
UINT CResourceSymbol::GetOriginalValue(void) const
{
	return m_uOriginalValue;
}


/// Get the modification flag of this symbol.
///
/// \return			The contents of m_bModified, which holds the modification flag for the symbol.
///
bool CResourceSymbol::IsModified(void) const
{
	return m_bModified;
}


/// Set/reset the modification flag of this symbol.
///
/// \param bModified	true if the symbol is to be marked as modifed, false otherwise.
/// \return				true if m_bModified was changed, false otherwise.
///
bool CResourceSymbol::SetModifiedFlag(bool bModified /*= true*/)
{
	if (m_bModified != bModified)
	{
		m_bModified = bModified;

		if (!m_bModified)
		{
			m_uOriginalValue = 0;
		}
		return true;
	}
	return false;
}


/// Get the Read Only flag of this symbol.
///
/// \return			The contents of m_bReadOnly, which holds the Read Only flag for the symbol.
///
bool CResourceSymbol::IsReadOnly(void) const
{
	return m_bReadOnly;
}


/// Set this symbol read only or read write.
///
/// \param bReadOnly	true if the symbol is to be Read Only, false otherwise
/// \return				true if m_bReadOnly was changed, false otherwise
///
bool CResourceSymbol::SetReadOnly(bool bReadOnly /*= true*/)
{
	if (m_bReadOnly != bReadOnly)
	{
		m_bReadOnly = bReadOnly;
	
		SetModifiedFlag();

		return true;
	}
	return false;
}


/// Get the user defined data with this symbol.
///
/// In normal operation this is usually a pointer to the CResourceSymbolManager object containing the symbol.
///
/// \return				The contents of m_nUserData, which holds the user data for the symbol.
///
INT_PTR CResourceSymbol::GetUserData(void) const
{
	return m_nUserData;
}

			
/// Set the value of m_nUserData, which can be used to store user defined data with this symbol.
///
/// In normal operation this is usually a pointer to the CResourceSymbolManager object containing the symbol.
///
/// \param nUserData	The user data to be set.
/// \return				true if m_nUserData was changed, false otherwise.
///
bool CResourceSymbol::SetUserData(INT_PTR nUserData)
{
	if (m_nUserData != nUserData)
	{
		m_nUserData = nUserData;

		return true;
	}
	return false;
}


/// Return a reference to the conflict list for this symbol.
///
/// \return			A reference to m_listConflicts.
///
CSymbolConflictList& CResourceSymbol::GetConflicts(void)
{
	return m_listConflicts;
}


/// Determine whether this symbol conflicts with others.
///
/// \return			true if m_listConflicts is not empty; false otherwise.
///
bool CResourceSymbol::HasConflicts(void) const
{
	return !m_listConflicts.IsEmpty();
}


/// Adds the given symbol to the list of conflicts (m_listConflicts).
///
/// \param pSymbol	A pointer to symbols to be removed.
/// \return			true if added, false otherwise.
///
bool CResourceSymbol::AddConflict(CResourceSymbol* pSymbol)
{
	if ( (NULL != pSymbol) && (this != pSymbol) )
	{
		if (NULL == m_listConflicts.Find(pSymbol) )
		{
			m_listConflicts.AddTail(pSymbol);

			return true;
		}
	}
	return false;
}



/// Removes the given symbol from the list of conflicts (m_listConflicts)
///
/// \param pSymbol	A pointer to the symbol to be removed from the list of conflicts.
/// \return			true if the symbol was removed successfully; false if not found.
///
bool CResourceSymbol::RemoveConflict(CResourceSymbol* pSymbol)
{
	POSITION pos = m_listConflicts.Find(pSymbol);
	if (NULL != pos)
	{
		m_listConflicts.RemoveAt(pos);

		return true;
	}
	return false;
}

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