Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / MFC
Article

Storing an array of properties in the Windows Registry

Rate me:
Please Sign up or sign in to vote.
3.11/5 (6 votes)
1 Jul 20033 min read 49.3K   486   13   3
MFC and Win API don't have functions that store arrays in the Windows Registry. This article describes the class based on MFC CArray class that does this task.

Sample Image - RegistryArray.gif

Introduction

MFC and Win API don’t have functions that store arrays in the Windows registry. This article describes the class based on MFC CArray class that solves this task. I used this class in the PC Atomic Sync project for storing the NTP (Network Time Protocol) servers list.

MFC registry functions

We use the registry to store program parameters.

If you use MFC, you must set the registry key for your program. MFC SDI and MDI wizard generates correspondent string in the App::InitInstance() function. In dialog based projects you can insert it manually.

Example:

SetRegistryKey(_T("RegistryArray"));

After calling this function, all your parameters will be stored in the registry path: HKEY_CURRENT_USER/Software/RegistryArray. As a result, in such multi-user systems as Win NT/XP/2K, every user will have his/her own set of parameters.

There are four MFC functions for writing/reading registry parameters: GetProfileInt, GetProfileString, WriteProfileInt, and WriteProfileString. They are members of the CWinApp class. The "Get" functions have a nice parameter for setting the default property. If the registry has not been yet initialized by your program, this parameter is used instead of the registry value.

Example:

// Writing integer value nSomeValue to the
// section SomeSection under name SomeValue.
AfxGetApp()->WriteProfileInt(_T("SomeSection"), 
                         _T("SomeValue"), nSomeValue );
// Reading nSomeValue from the key SomeValue of the section SomeSection.
// If the key is absent the variable will be assigned by 10.
int nSomeValue = AfxGetApp()->GetProfileInt(_T("SomeSection"), 
                                           _T("SomeValue"), 10);

Storing arrays in the registry

Usually we store data in files and program parameters in the registry. But it is possible that some parameters can look like an array. For example, our application has some windows and we want to store their placements. Every user would like a private placement. One solution is to create some file with parameters, the other is to store an array in the registry. There is no such standard function but the solution is simple. We can store the array size as an integer value and the array elements using special key names that include numbers of elements. For example, array_0, array_1, array_2 ...

CRegArray template class

It is good to have a common solution for any array that we want to store in the registry. So our class must be a template that receives any type. Mostly we work with classes and need to store records with data of different types. I created the CRegArray class template that is based on the CArray class template. There is only one demand to the class that is used as an array element. It must include two functions: CString GetAsString() const and void Parse(CString& sStr). I.e. the data converts to string before storing and restores from the string after reading from the registry.

Class source

#include <afxtempl.h>
template <class T, class F>
class CRegArray: public CArray<T, F>
{
public:
     CRegArray(const CString sSection, const CString sArrayName);
     void FetchRegistry();
     void PersistRegistry();
private:
     const CString m_sSection;
     const CString m_sArrayName;
     const CString m_sCounterName;
};
template <class T, class F>
inline CRegArray<T,T&>::CRegArray(const CString sSection, 
          const CString sArrayName):CArray<T,F>(),
          m_sSection(sSection),
          m_sArrayName(sArrayName),
          m_sCounterName(sArrayName+"_Counter")
{
}
template <class T, class F>
inline void CRegArray<T,T&>::FetchRegistry()
{
     int nCounter = 
       AfxGetApp()->GetProfileInt(m_sSection, m_sCounterName, 0);
     for(int i = 0; i < nCounter; i++){
          CString sElmName;
          sElmName.Format("%s %d",m_sArrayName, i);
          CString sTmp = 
             AfxGetApp()->GetProfileString(m_sSection, 
             sElmName, "");
          CSomeClass clTmp;
          clTmp.Parse(sTmp);
          Add(clTmp);
     }
}
template <class T, class F>
inline void CRegArray<T,T&>::PersistRegistry()
{
     AfxGetApp()->WriteProfileInt(m_sSection, 
                     m_sCounterName, GetSize() );
     for(int i=0;i<GetSize();i++){
          CString sElmName;
          sElmName.Format("%s %d",m_sArrayName, i);
          AfxGetApp()->WriteProfileString(m_sSection, 
                          sElmName, (*this)[i].GetAsString() ); 
     }
}

The class is simple. I added only two functions to the CArray class. They are FetchRegistry() and PersistRegistry(). The constructor has two parameters: the section name and the array name. So, it is possible to store some arrays in one section.

Demo project

The demo project is a dialog based project. To demonstrate the use of CRegArray I created CSomeClass. It includes string, double and integer fields. The object is entered in the dialog form and is added to the array by pressing the "Add Object" button. All objects are shown in the list control. "Delete Object" button removes the last object from the list. "Store into the registry" button writes the array into registry. This array is loaded in the OnInitDialog() function.

String converting of CSomeClass fields is realized in the following way:

const int nBuffSize(1024);
CString CSomeClass::GetAsString() const
{
     CString sStr(' ', nBuffSize);

     sStr.Format("%s\n%d\n%e", m_sStrValue, m_nIntValue,m_nDoubleValue);
     return sStr;
}
void CSomeClass::Parse(CString& sStr)
{
     strstream sStream((char*)(LPCTSTR)sStr, nBuffSize);
     char buff[nBuffSize];
     sStream.getline(buff,nBuffSize);
     m_sStrValue = buff;
     sStream >> m_nIntValue;
     sStream >> m_nDoubleValue;
}

Links

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
Ukraine Ukraine
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralHidden Regitry Data Value Pin
sbuonocore19-Jul-05 3:33
sbuonocore19-Jul-05 3:33 
QuestionREG_MULTI_SZ? Pin
Peter Ritchie9-Jul-03 3:20
Peter Ritchie9-Jul-03 3:20 
Questionhow about using CArchive Pin
Liorsh7-Jul-03 20:24
Liorsh7-Jul-03 20:24 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.