Click here to Skip to main content
15,895,836 members
Articles / Programming Languages / Visual Basic

A class for reading and writing the Windows Registry using VB.NET

Rate me:
Please Sign up or sign in to vote.
3.50/5 (22 votes)
24 Jun 2004CPOL6 min read 97.1K   35  
Reading and writing the Windows Registry overcoming the restrictions imposed by GetSetting and SaveSetting.
#if !defined(_REGISTRY_H_INCLUDED)
#define _REGISTRY_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/* Silence STL warnings */

#pragma warning (disable : 4786)
#pragma warning (disable : 4514)
#pragma warning (push, 3)

#ifdef _UNICODE
#if !defined(UNICODE)
#define UNICODE 
#endif
#endif

#include <windows.h>
#include <math.h>
#include <TCHAR.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <assert.h>


/* ====================================
 * Begin Preprocessor Definitions
 *
 * - Ugly, but well worth it.
 * ==================================== */


#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef	std::string tstring;
#endif


/* CRegistry Open Flags */

#define CREG_CREATE		1
#define CREG_AUTOOPEN	2
#define CREG_NOCACHE	4

/* CRegistry Behaivor flags */

#define CREG_LOADING	8


#define _MAX_REG_VALUE	2048	// Maximum Value length, this may be increased

#define NOT_ES(func)			func != ERROR_SUCCESS
#define IS_ES(func)				func == ERROR_SUCCESS
#define _R_BUF(size)			_TCHAR buffer[size]

#define REGENTRY_AUTO			__cregOwner->GetFlags() & CREG_AUTOOPEN
#define REGENTRY_TRYCLOSE		if (REGENTRY_AUTO) __cregOwner->AutoClose()
#define REGENTRY_SZ_SAFE		iType == REG_SZ || iType == REG_BINARY
#define REGENTRY_ALLOWCONV(b)	__bConvertable = b;


#define REGENTRY_REFRESH_IF_NOCACHE \
	if (__cregOwner->GetFlags() & CREG_NOCACHE && \
		REGENTRY_NOTLOADING && REGENTRY_KEYVALID( KEY_QUERY_VALUE ))\
		__cregOwner->Refresh();

#define REGENTRY_UPDATE_MULTISTRING \
	LPTSTR lpszBuffer = new _TCHAR[_MAX_REG_VALUE];	\
	REGENTRY_SETLOADING(+); GetMulti(lpszBuffer); REGENTRY_SETLOADING(-); \
	SetMulti(lpszBuffer, MultiLength(true), true); \
	delete [] lpszBuffer;

	
#define REGENTRY_KEYVALID(auto_access) \
	lpszName && ((REGENTRY_AUTO && __cregOwner->AutoOpen(auto_access)) || (!(REGENTRY_AUTO) && __cregOwner->hKey != NULL))

#define REGENTRY_NOTLOADING \
	!(__cregOwner->GetFlags() & CREG_LOADING)

#define REGENTRY_SETLOADING(op) \
	__cregOwner->__dwFlags op= CREG_LOADING

#define REGENTRY_BINARYTOSTRING \
	if (iType == REG_BINARY) { ForceStr(); lpszStr = *this; } 

#define REGENTRY_NONCONV_STORAGETYPE(type) \
	CRegEntry& operator=( type &Value ){ REGENTRY_ALLOWCONV(false) SetStruct(Value); return *this; }  \
	operator type(){ type Return; GetStruct(Return); return Return; }

#define REGENTRY_CONV_STORAGETYPE(type, to_sz, from_sz, from_dw, no_result) \
	CRegEntry& operator=( type Value ) { to_sz return (*this = (LPCTSTR)(buffer)); } \
	operator type(){ REGENTRY_BINARYTOSTRING return (REGENTRY_SZ_SAFE ? from_sz :(iType == REG_DWORD ? from_dw : no_result)); }

#define REGENTRY_CONV_NUMERIC_STORAGETYPE(type, maxlen, form, from_sz, from_dw) \
	REGENTRY_CONV_STORAGETYPE(type, _R_BUF(maxlen); _stprintf(buffer, _T(#form), Value);, from_sz, from_dw, 0)


/* ====================================
 * Include CRegEntry Class Definition
 * ==================================== */

#include "RegEntry.h"

/* ====================================
 * Begin CRegistry Class Definition
 * ==================================== */

using namespace std;

class CRegistry {

public:
	
	CRegistry	(DWORD flags = CREG_CREATE);	
	virtual		~CRegistry() { Close(); for (int i=0; i < _reEntries.size(); ++i) delete _reEntries[i]; delete [] _lpszSubKey; }

	CRegEntry&	operator[](LPCTSTR lpszVName);
	CRegEntry*	GetAt(size_t n) { assert(n < Count());  return _reEntries.at(n); }
	
	bool		Open(LPCTSTR lpszRegPath, HKEY hRootKey = HKEY_LOCAL_MACHINE,
				DWORD dwAccess = KEY_QUERY_VALUE | KEY_SET_VALUE, bool bAuto = false);
	
	bool		AutoOpen(DWORD dwAccess);
	void		AutoClose();
	void		Close();
	bool		Refresh();	

	static bool	KeyExists(LPCTSTR lpszRegPath, HKEY hRootKey = HKEY_LOCAL_MACHINE);
	bool		SubKeyExists(LPCTSTR lpszSub);	
	
	void		DeleteKey();	

	__inline	GetFlags()	{	return __dwFlags; }
	__inline	Count()		{	return _reEntries.size(); }
	
	HKEY		hKey;		/* Registry key handle */

protected:
	
	DWORD		__dwFlags;
	friend		void CRegEntry::MultiSetAt(size_t nIndex, LPCTSTR lpszVal);
	friend		void CRegEntry::MultiRemoveAt(size_t nIndex);

private:

	void		InitData();	
	void		DeleteKey(HKEY hPrimaryKey, LPCTSTR lpszSubKey);

	HKEY		_hRootKey;
	LPTSTR		_lpszSubKey;

	std::vector<CRegEntry *> _reEntries;
};

#pragma warning(pop)

#endif

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
Web Developer
Mexico Mexico
Sinhue Baez is a systems engineer. He started with computers in 1990, since then, he has programmed in BASIC, C/C++, COBOL, Pascal, Visual Basic, Java, Visual C++ and currently he is working using VB .NET and C#.
In his spare time he likes to code videogame demos with Visual C++ and Direct X.
He works as a project leader developing software for the production area of a food company.
Currently he is studying his master degree in Management Engineering.
He enjoys playing basketball, running and writing short stories.

Comments and Discussions