The registry is organized in an hierarchical format comprised of keys, entries and their associated values. Each key may contain one or more sub-keys (also known as keys) which in turn may contain additional sub-keys, entries and values. If you are confused, then the next few paragraphs will either lose you forever, or make it all crystal clear...
If you take a look at Windows Explorer (or Windows NT Explorer), you'll see an hierarchical arrangement (tree) in the left-hand pane indicating the drives and folders on your computer. The right-hand pane will display a list of drives, folders and files. The registry has an application that is roughly the equivalent of Windows Explorer, known as Regedit (the registry editor). Assuming you have access to the system registry, you can launch regedit by Clicking the "Start" button, and clicking "Run..." in the start menu. When the dialog appears, type "regedit" (with or without the quotes) and click "OK"
PLEASE NOTE: You can do serious and possibly irrepairable damage to your computer by tampering with the registry. Unless you are absolutely certain that you know what you are doing, do not add, change or delete anything in the registry using regedit.
| Item | Description | Item | Description |
| Drives | Your computer may contain one or more disk drives | Parent Key | The registry contains exactly six parent keys (described below) |
| Folder | Each drive on your computer may contain one or more folders. Each of these folders may themselves contain additional folders. | Child Key (or sub-key) | Each parent key may contain one or more child keys. Each of these may themselves contain additional sub-keys. |
| File | Within each folder there may exist one or more files. | Entry | Each key may contain a number of entries, some contain no entries at all (makes me wonder why they are even there). |
| File Data | Each file will contain some sort of data. It could be text data in a text or INI file, or it could be binary data representing image information, database data, spreadsheet data... | Value |
Each entry will have one value associated with it. The value can be
in one of three formats:
|
There is one additional similarity between Windows Explorer and Regedit; at the root of both is "My Computer," not actually a key, but I guess they had to start somewhere... Under "My Computer," are the Parent Keys (listed and described in the chart that follows).
| Key Name | Description |
HKEY_CLASSES_ROOT |
This key contains two categories of items
|
HKEY_CURRENT_USER |
This key contains a number of sub-keys, too numerous and varied (depending
upon O/S and the user's configuration) to list here. The one sub-key worth
mentioning is Software The Software sub-key contains numerous additional sub-keys (I'll give a detailed description of the software key(s) later in this document). |
HKEY_LOCAL_MACHINE |
This key contains a number of sub-keys including Hardware, Software and
System (there are others as well) each of which contains additional
sub-keys, entries and values.
|
HKEY_USERS |
This key contains a number of sub-keys, each of which describes a registered user of the computer. |
HKEY_CURRENT_CONFIG |
Another key that contains a Software sub-key along with a System key. There may be additional keys here as well. Whenever a new user logs on to a computer, that user's configuration settings are swapped into this parent key. |
HKEY_DYN_DATA |
As the name describes, this key contains application specific, dynamic data that can change while a program is running. |
Each application may have a number of keys, entries and associated values stored in the registry. The exact location will depend upon a number of factors, you can use these to help you determine where to store your application data.
As I indicated above, here is a description of the Software sub-keys. Every application that stores information in the registry will have a sub-key under one of the Software keys. However, some applications' sub-keys aren't directly under Software, they may be nested within other sub-keys. For example, large software vendors - especially those who have developed numerous applications - will have a sub-key for their company. The companies sub-key will contain additional sub-keys, one for each application that is installed on the computer.
Other software vendors (usually the smaller ones) will have a specific sub-key under one
of the software keys for each application they've released. Some will use the software
key under HKEY_CURRENT_USER, others will use HKEY_LOCAL_MACHINE
and still others will use both. The information that follows is a guide to help you decide
which of the Software keys you should use.
If you are developing an application that has user-specific settings, or will be registered
to a person (rather than a computer), then you probably want to store your registry information
in HKEY_CURRENT_USER\Software. If each user of your application will require
a license to operate your program - an ideal place to store the registration info would also
be under HKEY_CURRENT_USER\Software (you'd probably want to encrypt the data in
some form).
If your program has settings that are independent of the number of users then that information
may be stored under HKEY_LOCAL_MACHINE\Software. For instance, for an
internet-aware application, the ports that should be used to access the internet
could be stored here. If your program uses specific dynamic link libraries, on installation
of your program you can search for their location and store the paths in the registry.
Make a determination either while developing or before developing your program as to the best location for your registry information. If you plan on distributing numerous applications, you might want to consider creating a key for all apps developed by your company. Then, create a sub-key (under the company key) for each application.
#include <AtlBase.h>
Although there are numerous member functions of this class, I'm going to focus on only a few - the ones you'll most likely need to store your application settings. Those functions are:
LONG CRegKey::Open( HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired = KEY_ALL_ACCESS )The Open function gives access to a key within the registry if the key exists. This function (or the Create function) must be called prior to setting or querying any values contained in the registry.
The following code snippet will grant read access to a key called "MyProgram", assuming the key exists:
- The first parameter to this function is one of the pre-defined Parent keys (as listed in Chart 2).
- The second parameter is a null-terminated string containing the name of the key (or key and sub-key(s) combination) that you wish to access.
- The third (optional) parameter indicates the desired type of access. It has a default value of KEY_ALL_ACCESS, but you can substitute KEY_READ or KEY_WRITE for this value (additional values can be found in MSDN online).
- The return value from this function is ERROR_SUCCESS if successful or an error code if a problem occurred. This function will fail if the key specified by lpszKeyName doesn't exist
// This is how you'd get access to the registry for reading information CRegKey key; long nError = key.Open(HKEY_CURRENT_USER, "Software\\MyProgram", KEY_READ); if(nError == ERROR_SUCCESS) { // Code here to read values from MyProgram key }
LONG CRegKey::Create( HKEY hKeyParent, LPCTSTR lpszKeyName, LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE, REGSAM samDesired = KEY_ALL_ACCESS, LPSECURITY_ATTRIBUTES lpSecAttr = NULL, LPDWORD lpdwDisposition = NULL )The Create function performs essentially the same task as the Open function except that if the key does not already exist, it will create it.Rather than describe all the parameters here (you can find a full description at MSDN online), I'll only describe the ones most often used.
I would recommend using the Create function rather than the Open function when you need to store information in the registry. The first time your application runs, chances are that the registry keys used by your application do not yet exist. Since the Open function fails if the key doesn't exist, the Create function is better suited for writing data.
- The first parameter (as with the Open function) is one of the pre-defined Parent keys.
- The second parameter is a null terminated string specifying the key (or key and sub-key combination) that you wish to access.
- This function will return ERROR_SUCCESS if successful, or an error code if something went wrong.
// This is how you'd get access to the registry for writing information CRegKey key; long nError = key.Create(HKEY_CURRENT_USER, "Software\\MyProgram"); if(nError == ERROR_SUCCESS) { // Code here to write values to MyProgram key }
LONG CRegKey::SetValue( DWORD dwValue, LPCTSTR lpszValueName ) LONG CRegKey::SetValue( LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL )This function has been overloaded to allow storage of two different types of data; DWORD (an unsigned integer) and LPCTSTR (null-terminated character strings). In Chart 1 above, I indicated that three types of values can be stored in the registry, however CRegKey only provides support for two of them (there is currently no class-based support for storing binary data in the registry).Once you have access to a key within the registry, use this function to create or store entries and their values.
- The first parameter to both versions specifies the value that will be stored in the registry.
- The second parameter indicates the Entry name that the value will be associated with.
- The return value for this function is the same as all other CRegKey functions listed here.
CString sDefaultPath = "C:\\Program Files\\MyProgram\\"; CString sPathEntry = "Default Directory"; key.SetValue(sDefaultPath, sPathEntry); int nWindowWidth = 640; CString sWidthEntry = "Window Width"; key.SetValue(nWindowWidth, sWidthEntry);
LONG CRegKey::QueryValue( DWORD& dwValue, LPCTSTR lpszValueName ) LONG CRegKey::QueryValue( LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount )As with the SetValue function, this function is overloaded to allow the retrieval of two types of data: DWORD (unsigned integer) and LPTSTR (null-terminated character strings).Once you have read access to the registry, you can use this function to retrieve information contained in keys.
- The first parameter is the value to be retrieved. The first version of this function takes a reference to an unsigned integer value. If you're using a signed variable then it must be type-cast to (DWORD&).
The Second version of this function takes a pointer to a character buffer that will be filled with data retrieved from the registry.- The second parameter specifies the entry name that contains the sought value.
- The third parameter (only used in the second version of the function) is a pointer to a DWORD which indicates the size of the character buffer referred to by szValue. Execution of the QueryValue function resets this variable to the number of characters copied into the buffer.
CString sDefaultPath, sPathEntry = "Default Directory"; DWORD dwBufferSize = MAX_PATH; key.QueryValue( sDefaultPath.GetBuffer( dwBufferSize ), sPathEntry, &dwBufferSize ); sDefaultPath.ReleaseBuffer(); int nWindowWidth; CString sWidthEntry = "Window Width"; key.QueryValue( (DWORD&)nWindowWidth, sWidthEntry );
LONG CRegKey::Close(void)There are no parameters required for this function. After you've finished accessing the registry, you should call the Close function to release control of the registry.
For additional information on the CRegKey class, refer to the online documentation at http://msdn.microsoft.com/library/devprods/vs6/visualc/vcmfc/_atl_cregkey.htm