CRegConfig -- a Class to Easily Keep Your Data in the Registry

Environment: ATL/MFC, Windows

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 Kb
Download source - 2 Kb


Comments

  • Unable to store/retrieve data in user mode

    Posted by Tinoky on 03/17/2005 11:38am

    Your 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 ?

    Reply
  • Great job!

    Posted by rajeshm1975 on 01/08/2005 03:17am

    Just what I needed. Works like a charm and took only about 15 minutes to incorporate. Thanks!!

    Reply
  • REG_MULTI_SZ and deprecated functions

    Posted by DireWolf on 03/17/2004 07:37pm

    Very 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);
    		}
    	}
    }

    • Great job!

      Posted by rajeshm1975 on 01/08/2005 01:38am

      this 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!

      Reply
    • SetDWORDValue is not a Element of CRegKey

      Posted by ch_ri on 09/20/2004 06:27am

      if 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?

      Reply
    Reply
  • concat CString retrieved from registry error

    Posted by Legacy on 05/24/2003 12:00am

    Originally posted by: kristof cossement

    There is a problem with a retrieved String from the registry:
    
    

    If you try to concatenate a CString to the restreived CString it doesn't work because the retreived string is dubble string terminated with 00.

    // m_Config.m_strValue contains e.g. "test"
    CString str = m_Config.m_strValue;
    str += "hello";

    AfxMessageBox(str);

    shows "test" and not "testhello"


    Solved:

    instead of strValue.ReleaseBuffer(dwLen);
    use strValue.ReleaseBuffer();
    in RegConfig.cpp


    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there is simply not enough quality talent to go around. Tiempo Development is a nearshore software development company. Our headquarters are in AZ, but we are a pioneer and leader in outsourcing to Mexico, based on our three software development centers there. We have a proven process and we are experts at providing our customers with powerful solutions. We transform ideas into reality.

  • Lenovo recommends Windows 8 Pro. "I dropped my laptop getting out of the taxi." This probably sounds familiar to most IT professionals. If your employees are traveling, you know their devices are in for a rough go. Whether it's a trip to the conference room or a convention out of town, any time equipment leaves a user's desk it is at risk of being put into harm's way. Stay connected at all times, whether at the office or on the go, with agile, durable, and flexible devices like the Lenovo® …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date