A Class For Handling The Registry

Changes in Revision 2
Changes in Revision 3
Changes in Revision 4
Changes in Revision 5
Usage
Download

Often one can read in the newsgroups, that someone is looking for an MFC class that encapsulates the registry. In fact, MFC does not provide such a class. As long as one has no need to work with the registry in another location than HKEY_CURRENT_USER\Software\[<company>\]<product>, one can use CWinApp::GetProfile*() and CWinApp::WriteProfile*().

If one wants to use the registry more flexible, then one has to use the API-functions with their dozens of parameters. I don't know why MS doesn't provide a registry class in MFC - that would be quite easy ...

The CRegistry class I've developed allows one to use the registry in a simple way. In addition to the basic operations (loading and storing data), the class provides some more features. For instance one can walk the registry tree and perform some operations on any key/value-hit. Furthermore the class encapsulates differences between NT and Win95 (Aeh - you guessed that the Win32 API should be identical on both systems? Yes - the API is identical, but the performed action is not! Take a closer look at the description of the RegDeleteKey() function for instance.)

To handle all the different data types one can put into the registry, the CRegistry class uses an information holder class CRegVal. If you have to load a string from
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\DefaultUserName
you can do it as follows:

CString strKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon");
CRegistry reg(HKEY_LOCAL_MACHINE);  // otherwise it defaults to HKEY_CURRENT_USER
CString strDefaultUserName;
CRegVal regval;
if( reg.LoadKey(strKey, TEXT("DefaultUserName"), regval) )
        if( regval.GetValue(strDefaultUserName) )
                // yep - got the name
Simple datatypes (numbers and strings) will be supported directly by the CRegistry class, so you can write the sample above as follows:
CString strKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon");
CRegistry reg(HKEY_LOCAL_MACHINE);  // otherwise it defaults to HKEY_CURRENT_USER
CString strDefaultUserName;
if( reg.LoadKey(strKey, TEXT("DefaultUserName"), strDefaultUserName) )
        // yep - got the name
... but, if CRegistry::LoadKey() returns FALSE, this makes it harder to check whether the type of the registry key is wrong or the entry does not exist.

CRegistry doesn't support security (but that was no handicap for me so far :-)
 

Changes in Revision 2

You can use Registry.cpp if you want to use the registry classes in a non-MFC application and RegMFC.cpp in an MFC-based application. RegMFC.cpp will support some more methods for use with MFC.
For a build with MFC, you have to insert both files (Registry.cpp and RegMFC.cpp) into your project, but to exclude Registry.cpp from build.
In a non-MFC build you have to include Registry.cpp into your project only. In this case you don't need RegMFC.cpp.
Normally Registry.h detects whether you build an MFC version or not. If you want to build a non-MFC version in all circumstances, you can #define _REG_NO_MFC_BUILD.
Furthermore you can #define _REG_NO_TREEWALK to shrink the size of the resulting object files. This #define hides the CRegistry::RegistryTreeWalk() function and its associates. Use the _REG_NO_TREEWALK if you sure know, that you don't need the RegistryTreeWalk() method and want to reduce the code of your application/dll.
If you plan to use the CRegistry class in a non-MFC project you really should #define STRICT to make sure the class behaves correct in all circumstances. This is absolutly necessary, if you insert the class in a non-MFC dll that might be used in a MFC application.
CRegistry now is ready for use with UNICODE.

Changes in Revision 3

  • The RegistryTreeWalk() method no longer reports a wrong  "depth" to the methods OnValueHit() and OnKeyHit().
  • The member USHORT m_usDepth was deleted
  • eliminated a memory leak in DeleteKey()  (thanks to Tobias Krueger)
  • several bugfixes in DeleteKey() (sent in by Tobias Krueger)

 Changes in Revision 4

  • Some of the CRegVal::SetValue() methods changed. Most changes are for UNICODE applications (allocated too less memory). CRegVal::SetValue(const CStringArray &) is the only method that changes even for non-UNICODE applications. If you write CStringArrays to the registry, you really should upgrade to this revision!

Changes in Revision 5

  • Bug fixed in the RegTreeWalk-function (thanks to Pieter E. Roos and Daniel G. Hyams): The RegEnumValue()  function returns the number of bytes read in the last parameter. Since that value is stored in the CRegVal helper class, the next time RegVal was used to receive information from RegEnumValue(), RegEnumValue() thought that the buffer that it can put data in is smaller than it really is.
  • The sample is now a VC 6 project (sorry to all of you, who have only older versions of VC - but I have to be up to date ...)

Usage

If you want to use the class in a MFC environment, you have to include all three files to your project, but to exclude Registry.cpp from build. To do so, right-click the file in the FileView of the workspace window and select Settings ... . Make sure you select All Configurations. Now select the General page and check the field Exclude file from build.
In a pure Win32 project you will need Registry.[h|cpp] only.

CRegistry consists of three files:
Registry.h
Registry.cpp
RegMFC.cpp
Download Source 12 KB
Download Sample Project 28 KB

Date Last Updated: February 3, 1999