Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A(nother) C++ Registry Wrapper

0.00/5 (No votes)
21 Sep 2005 2  
Single header wrapper for registry manipulation.

Introduction

Yeah, I know. Another Windows registry wrapper? Sorry, but I needed something that sucked less than what I could find after chatting with Mr. Google. Let me know if you think I missed something out there.

The registry is sort of like a file system that contains a limited number of file types. I use Hive to indicate the top level root such as HKEY_CURRENT_USER, Key to indicate the hierarchical path, or folder, e.g., SOFTWARE\Microsoft\Office, and Value for the items that sit in a Key, like DWORDs or strings. Values have Names that would correspond to a file name in the file system analogy. Values are the contents of the file.

I don't like the kitchen sink approach to designing wrappers. The registry key class implements operator HKEY() const and operator HKEY&() so you can still easily use the standard API functions. The registry value class maps directly to the stock types. If you want to store something fancier, write a wrapper that populates the binary value type. The API sticks closely to the standard C API so if you already know how to use the registry you will feel right at home. For example, my RegKey::QueryValue just hides the usual RegQueryValueEx data size negotiation and has the same return value.

Using the code

The class RegValue is a variant that can contain any allowed registry value: REG_BINARY, REG_DWORD, REG_QWORD, REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ, or REG_NONE. A RegValue is a well behaved abstract data type that is safe to be used in STL containers. The type is determined by what you use to construct the RegValue. You can also directly manipulate the type and data if need be. Operator assignment from C++ types is supported and should work just like you would expect. A strict weak ordering is supplied by operator<.

RegKey provides the wrappers to the various system registry functions. It is also a well behaved abstract data type, but there is no optimization using smart pointers or such to avoid the expensive operation of opening or creating keys. The constructor takes the top level hive and an optional machine name for remote keys. The methods Open and Create call RegOpenKeyEx and RegCreateKeyEx and provide the option of overriding the default SAM of KEY_ALL_ACCESS. This class does not expose the SID.

The preferred way of getting and setting values is to use operator[]. This hides the mechanics of RegQueryValueEx and RegSetValueEx. For example:

RegKey key(HKEY_CURRENT_USER);
key.Open("Console");
RegValue value = key["CursorSize"];
if (value < RegValue(20))
    key["CursorSize"] = (DWORD)25;

changes the key HKCU\Console value CursorSize to 25 if it is a DWORD less than 20.

Forward iterators are provided for enumerating subkeys of a key and for enumerating all values in a key.

copy(RegKeyForwardIterator(key), RegKeyForwardIterator(), 
           ostream_iterator<TCHAR*>(cout, " "));

will print a space separated list of all subkeys of key. The iterator for values returns a pair<LPCTSTR,RegValue> containing the name and value pairs in a key.

RegValueForwardIterator i(key), e;
for (; i != e; ++i) {
    LPCTSTR name = (*i).first;
    RegValue value = (*i).second;
    if (value.Type == REG_SZ)
        cout << name << ": " << value.operator LPCTSTR() << endl;
}

prints out the name and value of all string types in key.

Neither of these iterators allow modification of registry entries.

Points of Interest

The proxy class for handling RegValue l-values is a little weak. I should probably provide more complete overriding of RegValue members.

History

  • June 20, 2005 - Initial release.

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