Click here to Skip to main content
15,896,453 members
Articles / Programming Languages / C++

Simple Stack-Based Wrapper for Windows and XML Registries

Rate me:
Please Sign up or sign in to vote.
4.19/5 (14 votes)
9 Aug 20049 min read 73.8K   796   19  
Left to my own devices, I tend to leak handles, leave keys open too long, close and re-open keys too often, and generally make a mess of the whole thing. And frankly, so do most of you (no insult intended).
#include <windows.h>

#include "Registry.h"
#include "RegistryImpl.h"

class RegValueImpl;
class RegKeyImpl;

////////////////////////////////////////////////////////////////////////////////
// class RegValueImpl
//
class RegValueImpl : public ValueImpl
{
public:
	RegValueImpl(KeyImpl* pSuper, LPCTSTR name);
	virtual ~RegValueImpl();

public:
	RegKeyImpl* Super();

	virtual bool Get(int& out);
	virtual bool Set(const int& in);

	virtual bool Get(double& out);
	virtual bool Set(const double& in);

	virtual bool Get(LPTSTR out, unsigned long size);
	virtual bool Set(LPCTSTR in);

	virtual bool Get(void* out, unsigned long size, unsigned long& out_count);
	virtual bool Set(void* in,  unsigned long size);
};

////////////////////////////////////////////////////////////////////////////////
// class RegKeyImpl
//

class RegKeyImpl : public KeyImpl
{
public:
	RegKeyImpl(KeyImpl* pSuper, LPCTSTR name)
		:	KeyImpl(pSuper, name),
			m_hKeyHandle(NULL)
	{}

	~RegKeyImpl()
	{
		if (m_hKeyHandle) ::RegCloseKey(m_hKeyHandle);
		m_hKeyHandle = NULL;
	}

public:
	virtual KeyImpl*	NewKeyImpl(KeyImpl* superKey, const char* name)
	{
		return new RegKeyImpl(superKey, name);
	}

	virtual ValueImpl*	NewValueImpl(KeyImpl* superKey, const char* name)
	{
		return new RegValueImpl(superKey, name);
	}

	virtual void Commit()
	{
	}

	RegKeyImpl* Super() { return static_cast<RegKeyImpl*>(m_pSuperKey); }

	HKEY
	GetOpenHKEY()
	{
		if (m_hKeyHandle == NULL) {
			HKEY superKey = Super()->GetOpenHKEY();
			if (superKey && (::RegOpenKeyEx(superKey, m_name, 0, KEY_ALL_ACCESS, 
				&m_hKeyHandle) != ERROR_SUCCESS))
			{
				if (::RegCreateKey(superKey, 
					m_name, &m_hKeyHandle) != ERROR_SUCCESS)
				{
					m_hKeyHandle = NULL;
				}
			}
		}
		return m_hKeyHandle;
	}

	HKEY
	AssertOpenHKEY()
	{
		if (GetOpenHKEY() == NULL) {
			HKEY superKey = Super()->AssertOpenHKEY();
			if (superKey && ::RegCreateKey(superKey, m_name, 
				&m_hKeyHandle) != ERROR_SUCCESS)
			{
				m_hKeyHandle = NULL;
			}
		}
		return m_hKeyHandle;
	}

public:
	HKEY		m_hKeyHandle;
};


////////////////////////////////////////////////////////////////////////////////
// class RegValueImpl - part 2
//
RegValueImpl::RegValueImpl(KeyImpl* pSuper, LPCTSTR name)
	: ValueImpl(pSuper, name)
{}

RegValueImpl::~RegValueImpl() 
{}

RegKeyImpl* 
RegValueImpl::Super()
{ 
	return static_cast<RegKeyImpl*>(m_pSuperKey); 
}

bool 
RegValueImpl::Get(int& out)
{
	unsigned long type = REG_DWORD;
	unsigned long size = sizeof(int);
	HKEY key = Super()->GetOpenHKEY();

	LONG ret = ::RegQueryValueEx(key, m_name, NULL, &type, (LPBYTE)&out, &size);

	return (ret == ERROR_SUCCESS);
}

bool 
RegValueImpl::Set(const int& in)
{
	unsigned long type = REG_DWORD;
	unsigned long size = sizeof(int);
	HKEY key = Super()->AssertOpenHKEY();

	LONG ret = ::RegSetValueEx(key, m_name, NULL, type, (LPBYTE)&in, size);

	return (ret == ERROR_SUCCESS);
}

bool 
RegValueImpl::Get(double& out)
{
	TCHAR buf[MAX_PATH]; 
	buf[0] = '\0';
	char* end = buf;
	
	bool status = Get(buf, MAX_PATH);
	if (status) {
		status = (buf != end);
		if (status)
			out = _tcstod(buf, &end);
	}

	return status;
}

bool 
RegValueImpl::Set(const double& in)
{
	TCHAR buf[MAX_PATH];
	sprintf(buf, "%g", in);

	return Set(buf);
}

bool 
RegValueImpl::Get(LPTSTR out, unsigned long size)
{
	unsigned long type = REG_SZ;
	HKEY key = Super()->GetOpenHKEY();

	LONG ret = ::RegQueryValueEx(key, m_name, NULL, &type, (LPBYTE)out, &size);
	
	return (ret == ERROR_SUCCESS);
}

bool 
RegValueImpl::Set(LPCTSTR in)
{
	unsigned long type = REG_SZ;
	unsigned long size = _tcslen(in) * sizeof(TCHAR);
	HKEY key = Super()->AssertOpenHKEY();

	LONG ret = ::RegSetValueEx(key, m_name, NULL, type, (LPBYTE)in, size);

	return (ret == ERROR_SUCCESS);
}

bool 
RegValueImpl::Get(void* out, unsigned long size, unsigned long& out_count)
{
	unsigned long type = REG_BINARY;
	HKEY key = Super()->GetOpenHKEY();

	out_count = size;
	LONG ret = ::RegQueryValueEx(key, m_name, NULL, &type, (LPBYTE)out, &out_count);

	return (ret == ERROR_SUCCESS);
}

bool 
RegValueImpl::Set(void* in, unsigned long size)
{
	unsigned long type = REG_BINARY;
	HKEY key = Super()->AssertOpenHKEY();

	LONG ret = ::RegSetValueEx(key, m_name, NULL, type, (LPBYTE)in, size);
	
	return (ret == ERROR_SUCCESS);
}

////////////////////////////////////////////////////////////////////////////////

RegKey		
RegKey::FromHKEY(HKEY root)
{
	RegKeyImpl* pImpl = NULL;

	TCHAR name[MAX_PATH];
	unsigned long size = MAX_PATH;

	if (::RegQueryInfoKey(root, name, &size, NULL, NULL, 
		NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
	{
		pImpl = new RegKeyImpl(NULL, name);
		pImpl->m_hKeyHandle = root;
	}

	return RegKey(pImpl);
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
A compiler warns of bogasity, ignore it at your peril. Unless you've done the compiler's job yourself, don't criticize it.

Comments and Discussions