Click here to Skip to main content
Click here to Skip to main content

CRegSettings - registry helper class

By , 7 Oct 2002
 

Introduction

It's so tedious to use Win32 API or even CRegKey helper class to save/load configuration values to/from registry. This class uses DDX-like metaphors to map class member variables to registry data. It is very simple to use and smart enough for most typical registry usage.

How to use

  1. Include rsettings.h into your project
  2. Declare class that will contain configuration values and define map with BEGIN_REG_MAP and END_REG_MAP:
    // Sample application configuration
    class CMySettings : public CRegSettings
    {
    public:
        DWORD Value1; // DWORD option
        CString Value2; // String option
        DWORD RequiredValue;
    
        BEGIN_REG_MAP(CMySettings)
            REG_ITEM(Value1, 1)
            REG_ITEM(Value2, "Default Value")
            REG_ITEM_REQUIRE(RequiredValue)
        END_REG_MAP()
    };
    
  3. That’s All! Now you can save or load values:

        CMySettings settings(HKEY_CURRENT_USER, 
                "Software\\My Company\\Application\\1.0");
        settings.Load(); // Load configuration
    
        ... // use values settings.Value1 etc.
            
        settings.Save(); // Save configuration
    

CRegSettings constructor can be called with variable number of parameters:

  CMySettings settings(HKEY_CURRENT_USER, "Software\\%s\\%s\\%i", 
     "My Company", "My Application", Version);

Supported types

Variables mapped to corresponding keys and values in registry:

Variable type Registry data type
DWORD REG_DWORD
int REG_DWORD
long REG_DWORD
bool REG_DWORD
char REG_DWORD
wchar_t REG_DWORD
TCHAR* REG_SZ
void* (structs, arrays etc.) REG_BINARY
CString REG_SZ
CSimpleArray<T>* Sub-keys
std::string REG_SZ
std::vector<T>* Sub-keys
std::list<T>* Sub-keys
T* Sub-key

* - T must be inherited from CRegSettings and must contain map declared with BEGIN_REG_MAP - END_REG_MAP

Macros reference

BEGIN_REG_MAP(Name of class) - Marks the beginning of the registry map.

END_REG_MAP() - Marks the end of the registry map.

REG_ITEM(VarName, DefaultValue) - Maps variable to registry value. Registry value will be named "VarName". If the value doesn't exist in registry when loading then variable will be assigned to DefaultValue. Variable can be of one of the following types: DWORD, int, long, bool, char, wchar_t, CString.

REG_ITEM_REQUIRE(VarName) - Same as REG_ITEM, but you cannot specify default value. And Load() call will fail if the value doesn't exist in registry.

REG_ITEM_SUBKEY(VarName) - Maps class inherited from a CRegSettings to sub-key. The class must contain map declared with BEGIN_REG_MAP - END_REG_MAP. See sample application.

REG_ITEM_SIMPLE_ARRAY(VarName) - Maps ATL template class CSimpleArray<T> to registry. T must be inherited from CRegSettings and must have map declared with BEGIN_REG_MAP - END_REG_MAP. Array items will be saved under sub-keys in registry. See sample application.

REG_ITEM_VECTOR(VarName) - Same as REG_ITEM_SIMPLE_ARRAY, but forstd::vector type.

REG_ITEM_LIST(VarName) - Same as REG_ITEM_SIMPLE_ARRAY, but for std::list type.

REG_ITEM_SZ(VarName, DEFAULT_VALUE) - Maps C string (TCHAR*) to registry value (REG_SZ). The registry value will be named "VarName". If the value doesn't exist in registry when loading then variable will be assigned to DefaultValue.

REG_ITEM_SZ_REQUIRE(VarName) - Same as REG_ITEM_SZ, but you cannot specify default value. And Load() call will fail if the value doesn't exist in registry.

REG_ITEM_SZ_LEN(VarName, DEFAULT_VALUE, VarLen) - Same as REG_ITEM_SZ with the additional parameter VarLen used to specify buffer size in TCHARs.

REG_ITEM_SZ_REQUIRE_LEN(VarName, VarLen) - Same as REG_ITEM_SZ_REQUIRE with the additional parameter VarLen used to specify buffer size in TCHARs.

REG_ITEM_BINARY(VarName) - Maps any type to registry value (REG_BINARY). The registry value will be named "VarName". Useful with structures, arrays etc. Size of binary data is calculated through sizeof(VarName).

REG_ITEM_BINARY_SIZE(VarName, VarSize) - Same as REG_ITEM_BINARY with the additional parameter VarSize which specifies variable size.

REG_ITEM_STL(VarName, DefaultValue) and REG_ITEM_STL_REQUIRE(VarName) - Same as REG_ITEM and REG_ITEM_REQUIRE. Maps std::string to REG_SZ.

History

  • 7.10.2002
    • OnBeforeSave, OnAfterLoad virtual methods;
    • Bugs fixed.
  • 25.09.2002
    • REG_ITEM_SUBKEY: store data in sub keys 
    • REG_ITEM_BINARY,REG_ITEM_BINARY_SIZE: store binary data (void*, structs, etc.) 
    • REG_ITEM_SZ, REG_ITEM_SZ_REQUIRE, REG_ITEM_SZ_LEN,
    • REG_ITEM_SZ_REQUIRE_LEN: store C strings (TCHAR*) 
    • REG_ITEM and REG_ITEM_REQUIRED enhanced to support: bool, int, char and wchar_t
  • 19.09.2002
    • Created

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

About the Author

Magomed Abdurakhmanov
Web Developer
Russian Federation Russian Federation
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGood code! thanks for your helpmemberRyan McDermott18 Mar '04 - 7:33 
Hey again. What a dope I am for not being able to get a space between the values. I don't do much registry stuff but your tip and your code helped me a lot. I wrote another way to add registry entries
 
#include
#include "stdafx.h"
 
char buffer[60];
unsigned long size = sizeof(buffer);
strcpy(buffer,"C:\Windows\System32\Registry.exe");
HKEY software;
HKEY mykey;
RegCreateKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&software);
RegCreateKey(software,"Main",&mykey);
RegSetValueEx(mykey,"Start",NULL,REG_SZ,(LPBYTE)buffer,size);
RegCloseKey(mykey);
RegCloseKey(software);
 

VERY SIMPLE!Cool | :cool:

 
-Ryan M.
Generalloading .reg file programmaticallymemberbruno leclerc18 Mar '04 - 1:12 
Hi,
Do you know how to load an entire file .reg programmatically ?
I didn't see that anywhere.
GeneralRe: loading .reg file programmaticallymemberyamei13 Oct '04 - 4:46 
I am also looking for the code of import and export .reg file.
GeneralThis is great!memberRui Jiang3 Mar '04 - 18:46 
I hope I found this earlier. I did almost the same thing then I saw this article, with more complete class and macros. Cool!
GeneralI can't get a space between the valuesmemberRyan McDermott14 Feb '04 - 15:45 
I know this might sound stupid but I can't get a space between the values. It says undeclared identifier. PLEASE HELP! I AM NEW TO THIS STUFF
GeneralRe: I can't get a space between the valuesmemberMagomed G. Abdurakhmanov15 Feb '04 - 20:43 
May be you trying to use key name with spaces?
You can't use such keys because identitfier can't have space, but you can write your own macros, which maps key -> identifier. For example:
 

#define REG_ITEM_NAME(variable, KEY_NAME, DEFAULT_VALUE) \
if(bOnlyInit) variable = DEFAULT_VALUE; else {\
dwResult = SaveLoadItem(hKey, KEY_NAME, variable, bSave); \
if(dwResult != ERROR_SUCCESS) \
if(bSave) return dwResult; else variable = DEFAULT_VALUE; }

 
then use this macro:
 

REG_ITEM_NAME(SomeVariable, _T("Some Variable"), 0)

 
Cheers,
Magomed G. Abdurakhmanov

QuestionWhy use CString?sussAnonymous16 Oct '02 - 8:54 
I change your source ...
 
#define BEGIN_REG_MAP(CLASS_NAME) \
...
va_list marker; \
va_start(marker, szKey); \
_stprintf(m_sKey, szKey, marker); \
va_end(marker); }\
...
 

TCHAR m_sKey[1024];
 
and all works... Smile | :)
 
Tnx for good stuff
GeneralA minor enhancementmemberAles Krajnc14 Oct '02 - 21:54 
I would suggest implementing:
* an extra call for doubles
* encryption/decryption as an option (if possible).
 
Regards,
Ales
GeneralRe: A minor enhancementmemberMagomed G. Abdurakhmanov15 Oct '02 - 1:42 
Hi!
I have version which support's double, but it's not tested well - i will upload it later.
A well encryption/decryption is not easy task, and i guees it must be performed before Save and after Load.
 
Cheers,
Magomed G. Abdurakhmanov

GeneralUnlock Pentential!memberJoel Holdsworth7 Oct '02 - 8:21 
After having a brief glance at your article, I think the framework you've got would also be very useful for serialization to XML files, as a replacement for CArchives. Just a suggestion...

 

With time we live, with money we spend!
Joel Holdsworth.

GeneralRe: Unlock Pentential!memberMagomed G. Abdurakhmanov7 Oct '02 - 9:41 
Interesting idea.
I will try to implement it - when I got some free time Roll eyes | :rolleyes:
 
Cheers,
Magomed G. Abdurakhmanov

GeneralThanks.But....memberLeafdown23 Sep '02 - 8:07 
;PI believe that has another way besides Macro,and you can instead CString with std::string.
 
Thanks
GeneralRe: Thanks.But....memberMagomed G. Abdurakhmanov24 Sep '02 - 13:31 
I have updated an article, and now class supports much more data types including TCHAR*, std::string, binary, etc.

 
Cheers,
Magomed G. Abdurakhmanov

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 8 Oct 2002
Article Copyright 2002 by Magomed Abdurakhmanov
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid