CRegConfig -- a Class to Easily Keep Your Data in the Registry
Well, here is a class to easily read/write your data from/to the Registry. It's quite simple to use and it's very powerful. Common features are:
- CRecordset-like structure.
- Autoload and autosave configuration.
- Support for STRING, DWORD, and BINARY data.
- Adding new data is very easy.
- Warning level 4 complaint.
Here are the main parts of the CRegConfig class:
- Constructor (initialize base class object here to allow autoload).
- SetRegKey() function—to set a Registry key, where you will keep your settings.
- Load() and Save() functions—for loading and saving.
- Transfer() functions—they are taking care of each data member.
- TransferAllData() pure virtual function—its purpose is to handle loading and saving of all your data members.
- Data members.
How does it all work? The CRegConfig class is abstract (it has one pure virtual function). So, it cannot be instantiated directly. You should derive your class from it and override this function. Common steps are:
- Derive your own class from CRegConfig (if you want to use autoload, supply a special constructor).
- Add all data members you need to keep in the Registry.
- Override the TransferAllData() function so that it will call the Transfer() function for each of your data members.
- Instantiate your class and enjoy.
Let's look at the technique in more details:
class CMyRegConfig : public CRegConfig
{
public:
CMyRegConfig();
virtual ~CMyRegConfig();
// data members
DWORD m_dwValue;
CString m_strValue;
CByteArray m_bData;
protected:
virtual void TransferAllData(BOOL bSave);
// overridden pure virtual function to save and load our data
};
Next, the implementation:
CMyRegConfig::CMyRegConfig() : CRegConfig(HKEY_LOCAL_MACHINE,
"Software\\test")
// initializing our class to operate with the
// "HKLM\software\test" registry key
{
// set default values for our settings
// they are used on the first start (if data is not present
// in then Registry)
m_dwValue=100;
m_strValue="Sample string";
Load(); // we can use autoload because we have initialized
// the CRegConfig class
}
CMyRegConfig::~CMyRegConfig()
{
Save(); // you can add automatic saving of config on
// destruction
}
void CMyRegConfig::TransferAllData(BOOL bSave)
{
// Add a Transfer() function for each data member in your class
Transfer(bSave, "Dword", m_dwValue);
// The first parameter is always bSave.
// The second parameter is a value name in the Registry.
// The third one is a reference to a data member.
Transfer(bSave, "String", m_strValue);
Transfer(bSave, "Binary", m_bData);
}
The next step is declaring the CMyRegConfig object. It will read settings from Registry during construction. Then, you can access them as usual member variables: you can read and modify them. Then, during destruction, this class will save your data. Also, you can always load/save data manually.
If you will need to add one more data member to the configuration, just add a data member to your class and add a corresponding Transfer() call to the TransferAllData() function.
That's all. I hope it will help you.
Downloads
Download demo project - 17 KbDownload source - 2 Kb

Comments
Unable to store/retrieve data in user mode
Posted by Tinoky on 03/17/2005 11:38amYour class is simply great! I like it very much. It works pretty well in administrator mode, but using HKEY_LOCAL_MACHINE seams to be forbiden in user mode. The data I need to store/retrieve must be accessible for any user of the PC. I thought I should use HKEY_USERS, but it still doesn't work. Any Idea ?
ReplyGreat job!
Posted by rajeshm1975 on 01/08/2005 03:17amJust what I needed. Works like a charm and took only about 15 minutes to incorporate. Thanks!!
ReplyREG_MULTI_SZ and deprecated functions
Posted by DireWolf on 03/17/2004 07:37pmVery Useful! I've changed the Transfer functions as follows to replace the deprecatef ATL::CRegKey::QueryValue and ATL::CRegKey::SetValue and add support for REG_MULTI_SZ: void CRegConfig::Transfer(BOOL bSave, LPCTSTR strValueName, DWORD &dwValue) { if(bSave) m_rKey.SetDWORDValue(strValueName, dwValue); else m_rKey.QueryDWORDValue(strValueName,dwValue); } void CRegConfig::Transfer(BOOL bSave, BOOL bMulti, LPCTSTR strValueName, CString &strValue) { if(bMulti) { if(bSave) m_rKey.SetMultiStringValue(strValueName, strValue); else { DWORD dwLen; LPTSTR lpStr; if(m_rKey.QueryMultiStringValue(strValueName, NULL, &dwLen)==ERROR_SUCCESS) { lpStr=strValue.GetBuffer(dwLen+1); m_rKey.QueryMultiStringValue(strValueName, lpStr, &dwLen); strValue.ReleaseBuffer(); } } } else { if(bSave) m_rKey.SetStringValue(strValueName, strValue); else { DWORD dwLen; LPTSTR lpStr; if(m_rKey.QueryStringValue(strValueName, NULL, &dwLen)==ERROR_SUCCESS) { lpStr=strValue.GetBuffer(dwLen+1); m_rKey.QueryStringValue(strValueName, lpStr, &dwLen); strValue.ReleaseBuffer(); } } } } void CRegConfig::Transfer(BOOL bSave, LPCTSTR strValueName, CByteArray &bValue) { DWORD dwLen, dwType; LPBYTE lpData; if(bSave) { dwLen=bValue.GetSize(); lpData=bValue.GetData(); //RegSetValueEx(m_rKey.m_hKey, strValueName, 0, REG_BINARY, lpData, dwLen); m_rKey.SetBinaryValue(strValueName, lpData, dwLen); } else { dwType=REG_BINARY; if(RegQueryValueEx(m_rKey.m_hKey, strValueName, NULL, &dwType, NULL, &dwLen)==ERROR_SUCCESS) { bValue.RemoveAll(); bValue.SetSize(dwLen); lpData=bValue.GetData(); RegQueryValueEx(m_rKey.m_hKey, strValueName, NULL, &dwType, lpData, &dwLen); } } }-
-
ReplyGreat job!
Posted by rajeshm1975 on 01/08/2005 01:38amthis class is just what i was looking for. i needed to create an app that reads/writes properties to the registry and I came across this class. It made life so easy! Good Job!
ReplySetDWORDValue is not a Element of CRegKey
Posted by ch_ri on 09/20/2004 06:27amif i insert this code i get this message: SetDWORDValue is not a Element of CRegKey So whith class do you use? Or what else do you change?
Replyconcat CString retrieved from registry error
Posted by Legacy on 05/24/2003 12:00amOriginally posted by: kristof cossement
Reply