Click here to Skip to main content
15,891,864 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 532.8K   12.1K   201  
An application/add-in to organise and renumber resource symbol IDs
//////////////////////////////////////////////////////////////////
// Registry.cpp
// A simple registry class
// Julian Smart

#include "stdafx.h"
#include "NGUtils.h"
#include "NGRegistry.h"
#include "winreg.h"


// RegisterApp:
// HKEY_CLASSES_ROOT\.ext = appId
// HKEY_CLASSES_ROOT\appId = typeName
// HKEY_CLASSES_ROOT\appId\DefaultIcon = defaultIcon
// where typeName is the human-readable form of appId.	
//
// If contentType is specified, the MIME type is stored:
// HKEY_CLASSES_ROOT\.ext\Content Type = contentType
//
// If you don't have an extension to register, then
// you don't need to call RegisterApp.

BOOL CNGRegistry::RegisterApp(const CString& ext, const CString& appId,
		const CString& typeName, const CString& defaultIcon, const CString& contentType)
{
	UNREFERENCED_PARAMETER(contentType);
	UNREFERENCED_PARAMETER(defaultIcon);
	UNREFERENCED_PARAMETER(appId);

/*
	HKEY hKey = 0;
	long ret = ::RegOpenKey(HKEY_CLASSES_ROOT, (const char *) ext, &hKey);
	if (ret != ERROR_SUCCESS)
	{
		ret = ::RegCeateKey(HKEY_CLASSES_ROOT, (const char *) ext, &hKey);
		if (ret != ERROR_SUCCESS)
			return FALSE;
	}
*/

	long ret = ::RegSetValue(HKEY_CLASSES_ROOT, (const char *) ext, REG_SZ,
		(const char *) typeName, typeName.GetLength());
	if (ret != ERROR_SUCCESS)
		return FALSE;
	return TRUE;
}

BOOL CNGRegistry::HaveRegistered(const CString& appId) const
{
	HKEY hKey = 0;
	long ret = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, (const char *) appId,
		0, KEY_READ, & hKey);

	if (ret == ERROR_SUCCESS)
	{
		::RegCloseKey(hKey);
		return TRUE;
	}
	else
		return FALSE;
}

// Get the name corresponding to this extension, or FALSE
BOOL CNGRegistry::GetExtension(const CString& ext, CString& appName)
{
	char buf[256];
	long sz = 0;
	long ret = ::RegQueryValue(HKEY_CLASSES_ROOT, (const char *)ext,
		buf, &sz);
	if (ret == ERROR_SUCCESS)
	{
		appName = buf;
		return TRUE;
	}
	else
		return FALSE;
}

// Determine how the app will be opened
// HKEY_CLASSES_ROOT\appId\shell\open\command = openCommand
// HKEY_CLASSES_ROOT\appId\shell\open\ddeexec = ddeCommand
BOOL CNGRegistry::RegisterShellOpen(const CString& appId, const CString& openCommand,
		const CString& ddeCommand)
{
	UNREFERENCED_PARAMETER(appId);
	UNREFERENCED_PARAMETER(ddeCommand);
	UNREFERENCED_PARAMETER(openCommand);

	return TRUE;
}


// Register a sound event (user must then associate sound using Control
// Panel)
// HKEY_CURRENT_USER\AppEvents\Event Labels\eventName = readableEventName
BOOL CNGRegistry::RegisterSound(const CString& eventName, const CString& readableEventName)
{
	UNREFERENCED_PARAMETER(readableEventName);
	UNREFERENCED_PARAMETER(eventName);

	return TRUE;
}

//////////////////////////////////////////////////////////////////
// GENERIC FUNCTIONS

// System-wide stuff, e.g. home directory
// HKEY_CLASSES_ROOT\appId\key = value
BOOL CNGRegistry::SetSystemEntry(const CString& appId, const CString& key, const CString& value)
{
	CString key1(appId);
	key1 += CString("\\") + key;

	return SetEntry(CNGRegistry_SYSTEM, key1, value);
}

BOOL CNGRegistry::SetSystemEntry(const CString& appId, const CString& key, const long value)
{
	CString key1(appId);
	key1 += CString("\\") + key;

	return SetEntry(CNGRegistry_SYSTEM, key1, value);
}

// Does the key exist?
BOOL CNGRegistry::HasSystemKey(const CString& appId, const CString& key)
{
	CString key1(appId);
	key1 += CString("\\") + key;

	return HasKey(CNGRegistry_SYSTEM, key1);
}

// Get the entry
BOOL CNGRegistry::GetSystemEntry(const CString& appId, const CString& key, CString& value)
{
	CString key1(appId);
	key1 += CString("\\") + key;

	return GetEntry(CNGRegistry_SYSTEM, key1, value);
}

BOOL CNGRegistry::GetSystemEntry(const CString& appId, const CString& key, long& value)
{
	CString key1(appId);
	key1 += CString("\\") + key;

	return GetEntry(CNGRegistry_SYSTEM, key1, value);
}

// User-specific data, e.g. user's current home directory
// HKEY_CURRENT_USER\SOFTWARE\appId\key = value
BOOL CNGRegistry::SetUserEntry(const CString& appId, const CString& key, const CString& value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return SetEntry(CNGRegistry_USER, key1, value);
}

BOOL CNGRegistry::SetUserEntry(const CString& appId, const CString& key, const long value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return SetEntry(CNGRegistry_USER, key1, value);
}

// Does the key exist?
BOOL CNGRegistry::HasUserKey(const CString& appId, const CString& key)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return HasKey(CNGRegistry_USER, key1);
}

// Get the entry
BOOL CNGRegistry::GetUserEntry(const CString& appId, const CString& key, CString& value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return GetEntry(CNGRegistry_USER, key1, value);
}

BOOL CNGRegistry::GetUserEntry(const CString& appId, const CString& key, long& value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return GetEntry(CNGRegistry_USER, key1, value);
}

// Machine-specific data, such as data common to all users.
// HKEY_LOCAL_MACHINE\SOFTWARE\appId\key = value
BOOL CNGRegistry::SetMachineEntry(const CString& appId, const CString& key, const CString& value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return SetEntry(CNGRegistry_MACHINE, key1, value);
}

BOOL CNGRegistry::SetMachineEntry(const CString& appId, const CString& key, const long value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return SetEntry(CNGRegistry_MACHINE, key1, value);
}

// Does the key exist?
BOOL CNGRegistry::HasMachineKey(const CString& appId, const CString& key)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return HasKey(CNGRegistry_MACHINE, key1);
}

// Get the entry
BOOL CNGRegistry::GetMachineEntry(const CString& appId, const CString& key, CString& value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return GetEntry(CNGRegistry_MACHINE, key1, value);
}

BOOL CNGRegistry::GetMachineEntry(const CString& appId, const CString& key, long& value)
{
	CString key1("SOFTWARE\\");
	if (m_organisation != "")
		key1 += m_organisation + CString("\\") ;
	key1 += appId + CString("\\") + key;

	return GetEntry(CNGRegistry_MACHINE, key1, value);
}

//////////////////////////////////////////////////////////////////
// GENERAL REGISTRY FUNCTIONS

int CNGRegistry::ParseMajorKey(const CString& sMajorKey)
{
	int eMajorKey = -1;
	if (0 == sMajorKey.CompareNoCase(_T("HKEY_CLASSES_ROOT")) )
	{
		eMajorKey = CNGRegistry_SYSTEM;
	}
	else if (0 == sMajorKey.CompareNoCase(_T("HKEY_CURRENT_USER")) )
	{
		eMajorKey = CNGRegistry_USER;
	}
	else if (0 == sMajorKey.CompareNoCase(_T("HKEY_LOCAL_MACHINE")) )
	{
		eMajorKey = CNGRegistry_MACHINE;
	}
	return eMajorKey;
}


BOOL CNGRegistry::SetEntry(const CString& rsKey, const CString& Value)
{
	CString sMajorKey	= ::Before(rsKey, _T("\\") );
	CString sSubKey		= ::After(rsKey, _T("\\") );

	int eMajorKey = ParseMajorKey(sMajorKey);
	if (eMajorKey >=0)
	{
		return SetEntry(eMajorKey, sSubKey, Value);
	}
	return FALSE;
}


BOOL CNGRegistry::SetEntry(const CString& rsKey, const long Value)
{
	CString sMajorKey	= ::Before(rsKey, _T("\\") );
	CString sSubKey		= ::After(rsKey, _T("\\") );

	int eMajorKey = ParseMajorKey(sMajorKey);
	if (eMajorKey >=0)
	{
		return SetEntry(eMajorKey, sSubKey, Value);
	}
	return FALSE;
}



BOOL CNGRegistry::SetEntry(const int majorKey, const CString& subKey, const CString& value)
{
	HKEY hMajorKey = 0;
	switch (majorKey)
	{
		case CNGRegistry_SYSTEM:
			{
				hMajorKey = HKEY_CLASSES_ROOT;
				break;
			}
		case CNGRegistry_USER:
			{
				hMajorKey = HKEY_CURRENT_USER;
				break;
			}
		case CNGRegistry_MACHINE:
			{
				hMajorKey = HKEY_LOCAL_MACHINE;
				break;
			}
		default:
			return FALSE;

	}

	CString actualKey, name;
	SplitKeyName(subKey, actualKey, name);

	HKEY hKey = 0;
	long ret = ::RegOpenKeyEx(hMajorKey, (const char *) actualKey,
		0, KEY_ALL_ACCESS, & hKey);

	if (ret != ERROR_SUCCESS)
	{
		// Create key
		char classType[1];
		classType[0] = 0;
		DWORD disposition = 0;
		ret = ::RegCreateKeyEx(hMajorKey, (const char *) actualKey,
			0, classType, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
			& hKey, & disposition);

		if (ret != ERROR_SUCCESS)
			return FALSE;
	}

	DWORD reserved = 0;
	DWORD type = REG_SZ;
	BYTE *buf = new BYTE[value.GetLength() + 1];
	strcpy((char *)buf, (const char *) value);
	DWORD sz = value.GetLength() + 1;
	ret = ::RegSetValueEx(hKey, (const char *) name, reserved, 
		type, buf, sz);
	delete[] buf;
	
	::RegCloseKey(hKey);
	
	if (ret == ERROR_SUCCESS)
	{
		return TRUE;
	}
	else
		return FALSE;
}

BOOL CNGRegistry::SetEntry(const int majorKey, const CString& subKey, const long value)
{
	CString valueStr;
	valueStr.Format("%ld", value);
	return SetEntry(majorKey, subKey, valueStr);
}

// Does the key exist?
BOOL CNGRegistry::HasKey(const int majorKey, const CString& subKey)
{
	HKEY hMajorKey = 0;
	switch (majorKey)
	{
		case CNGRegistry_SYSTEM:
			{
				hMajorKey = HKEY_CLASSES_ROOT;
				break;
			}
		case CNGRegistry_USER:
			{
				hMajorKey = HKEY_CURRENT_USER;
				break;
			}
		case CNGRegistry_MACHINE:
			{
				hMajorKey = HKEY_LOCAL_MACHINE;
				break;
			}
		default:
			return FALSE;

	}
	CString actualKey, name;
	SplitKeyName(subKey, actualKey, name);

	HKEY hKey = 0;
	long ret = ::RegOpenKeyEx(hMajorKey, (const char *) actualKey,
		0, KEY_READ, & hKey);

	if (ret == ERROR_SUCCESS)
	{
		::RegCloseKey(hKey);
		return TRUE;
	}
	else
		return FALSE;
}

// Get the entry
BOOL CNGRegistry::GetEntry(const CString& rsKey, CString& Value)
{
	CString sMajorKey	= ::Before(rsKey, _T("\\") );
	CString sSubKey		= ::After(rsKey, _T("\\") );

	int eMajorKey = ParseMajorKey(sMajorKey);
	if (eMajorKey >=0)
	{
		return GetEntry(eMajorKey, sSubKey, Value);
	}
	return FALSE;
}


BOOL CNGRegistry::GetEntry(const CString& rsKey, long& Value)
{
	CString sMajorKey	= ::Before(rsKey, _T("\\") );
	CString sSubKey		= ::After(rsKey, _T("\\") );

	int eMajorKey = ParseMajorKey(sMajorKey);
	if (eMajorKey >=0)
	{
		return GetEntry(eMajorKey, sSubKey, Value);
	}
	return FALSE;
}


BOOL CNGRegistry::GetEntry(const int majorKey, const CString& subKey, CString& value)
{
	HKEY hMajorKey = 0;
	switch (majorKey)
	{
		case CNGRegistry_SYSTEM:
			{
				hMajorKey = HKEY_CLASSES_ROOT;
				break;
			}
		case CNGRegistry_USER:
			{
				hMajorKey = HKEY_CURRENT_USER;
				break;
			}
		case CNGRegistry_MACHINE:
			{
				hMajorKey = HKEY_LOCAL_MACHINE;
				break;
			}
		default:
			return FALSE;

	}

	CString actualKey, name;
	SplitKeyName(subKey, actualKey, name);

	HKEY hKey = 0;
	long ret = ::RegOpenKeyEx(hMajorKey, actualKey,
		0, KEY_READ, &hKey);

	if (ret == ERROR_SUCCESS)
	{
//		DWORD reserved = 0;
		DWORD type = 0;
		BYTE buf[256];
		DWORD sz = 256;
		ret = ::RegQueryValueEx(hKey, name, NULL, 
			&type,buf, &sz);

//		ret = ::RegQueryValueEx(hKey, name, &reserved, 
//			&type,buf, &sz);

		::RegCloseKey(hKey);

		if (ret == ERROR_SUCCESS)
		{
			return ConvertToString(buf, type, value);
		}
		else
		{
#ifdef _DEBUG
			LPVOID lpMsgBuf;
			::FormatMessage( 
				FORMAT_MESSAGE_ALLOCATE_BUFFER | 
				FORMAT_MESSAGE_FROM_SYSTEM | 
				FORMAT_MESSAGE_IGNORE_INSERTS,
				NULL,
				::GetLastError(),
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
				(LPTSTR) &lpMsgBuf,
				0,
				NULL 
			);
			TRACE1("::RegQueryValueEx() failed. Error: %s\n", lpMsgBuf);

			// Free the buffer.
			LocalFree( lpMsgBuf );
#endif
			return FALSE;
		}
	}
	else
		return FALSE;
}

BOOL CNGRegistry::GetEntry(const int majorKey, const CString& subKey, long& value)
{
	CString str;
	if (GetEntry(majorKey, subKey, str))
	{
		value = atol((const char *)str);
		return TRUE;
	}
	else
		return FALSE;
}

// KEY\Name -> Key, Name
// Name -> "", Name
BOOL CNGRegistry::SplitKeyName(const CString& keyName, CString& key, CString& name)
{
	int i = keyName.GetLength() - 1;
	while (i >= 0)
	{
		if (keyName[i] == '\\')
		{
			key = keyName.Left(i);
			name = keyName.Right(keyName.GetLength() - i - 1);
			return TRUE;
		}
		i --;
	}
	key = "";
	name = keyName;
	return TRUE;
}

// Convert whatever type it is, to a string.
BOOL CNGRegistry::ConvertToString(const BYTE buf[], const DWORD type, CString& str)
{
	BOOL bResult = FALSE;

	switch (type)
	{
		case REG_DWORD:
			{
				char buf2[20];
				sprintf(buf2, "%ld", (DWORD) buf);
				str = buf2;
				bResult = TRUE;
				break;
			}

		case REG_SZ:
		case REG_EXPAND_SZ:
			str = buf;
			bResult = TRUE;
			break;

		case REG_BINARY:
			str = "Binary data"; // Can't deal with it
			bResult = FALSE;
			break;

		default:
			str = "Can't convert to string";
			bResult = FALSE;
			break;
	}
	return bResult;
}

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