Using the Windows Registry

PC Repair Tools

Advanced Registry Cleaner PC Diagnosis and Repair

Get Instant Access

The Windows registry is a general-purpose mechanism that applications (and Windows itself) use to store program information that must be retained when an application terminates. The information is stored in a hierarchical format. You can use the Registry Editor program (Regedit.exe) that comes with Windows to examine (and, if you're very brave, even modify) the contents of the registry on your machine.

The information in the registry is organized by keys, which are often written in the syntax of directory paths. For example, in the Registry Editor, you can find the key

HKEY_CURRENT_USER\Software\Microsoft\Notepad to examine all the information stored in the registry by the Microsoft Notepad program. Each piece of information has a name (for example, iPointSize and iWindowPosX), a type (in both these cases, a REG_DWORD, which is a 32-bit unsigned integer), and a value.

The Windows registry is supported with two classes in the Microsoft.Win32 namespace. The Registry class consists solely of seven static read-only fields for the seven possible root keys in the registry. The Description column shows how these root keys are defined in the Win32 header files and displayed in the Registry Editor:

Registry Static Fields

Type

Field

Accessibility

Description

RegistryKey

ClassesRoot

read-only

HKEY CLASSES ROOT

RegistryKey

CurrentUser

read-only

HKEY CURRENT USER

RegistryKey

LocalMachine

read-only

HKEY_LOCAL_MACHINE

RegistryKey

Users

read-only

HKEY USERS

RegistryKey

PerformanceData

read-only

HKEY PERFORMANCE DATA

RegistryKey

CurrentConfig

read-only

HKEY CURRENT CONFIG

RegistryKey

DynData

read-only

HKEY_DYN_DATA

Most applications will probably restrict themselves to the CurrentUser key to store user-specific information such as favorite fonts, colors, and other settings.

The second class is RegistryKey. The following methods are probably the most common: RegistryKey Methods (selection)

RegistryKey CreateSubKey(string strSubKey) RegistryKey OpenSubKey(string strSubKey)

RegistryKey OpenSubKey(string strSubKey, bool bWritable) void SetValue(string strName, objeet obj) objeet GetValue(string strName) void Close()

Notice that the CreateSubKey and OpenSubKey methods are members of the RegistryKey class and also return RegistryKey objects. The first RegistryKey object you obtain is from one of the fields of the Registry class, for example:

RegistryKey regkey = Registry.CurrentUser;

You then obtain another RegistryKey object by combining that registry key with a subkey argument passed to CreateSubKey or OpenSubKey. For example, if regkey has been obtained from Registry.CurrentUser, the call regkey = regkey.OpenSubKey("Software\\Microsoft\\Notepad");

returns a registry key suitable for reading the information stored by Notepad. Or you can do both calls in one shot:

RegistryKey regkey =

Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Notepad");

But that call obtains the key for Notepad. That's not the key you want to use for your application. You'll want to make your own key using the CreateSubKey method, for example:

RegistryKey regkey =

Registry.CurrentUser.CreateSubKey("Software\\MyCompany\\MyApp");

You'll probably use CreateSubKey when your program is first installed or the first time it runs. Subsequently, you can use OpenSubKey to open the key for reading:

RegistryKey regkey =

Registry.CurrentUser.OpenSubKey("Software\\MyCompany\\MyApp");

You can also use OpenSubKey to open the key for writing:

RegistryKey regkey =

Registry.CurrentUser.OpenSubKey("Software\\MyCompany\\MyApp", true);

After you're finished accessing the registry, close it like so:

regkey.Close();

The SetValue and GetValue methods let you read and write values associated with names. But watch out: the syntax of the SetValue call makes it appear as if you can use an object of any type as the second argument, for example, an object of type Font:

regkey.SetValue("MyFont" , font);

This call will work (kind of), but the problem arises when you try to retrieve that same object with a call to GetValue:

font = (Font) regkey.GetValue("MyFont"); // Won't work!

If the registry had been originally designed with an object-oriented interface in mind, these two calls might work. But it wasn't, and they won't. Basically, you're limited to storing strings, 32-bit integers, and byte arrays. (A byte array lets you store generalized binary information, though probably not as conveniently as you'd like.)

The SetValue call just shown actually stores font.ToString(), which is a string that describes the Font object. When you call GetValue, however, that string can't be cast into an object of type Font, and the invalid cast will cause a run-time exception. If you need to store an object of type Font in the registry, you must store everything you need to re-create the font in the form of strings, 32-bit integers, and byte arrays.

Let's look at an example. The DialogsWithRegistry class in the following program subclasses BetterFontAndColorDialogs and adds registry support. The seven const fields define the registry key and all the registry names I use in the program.

DialogsWithRegistry.es

//--------------------------------------------------

// DialogsWithRegistry.es ® 2001 by Charles Petzold //--------------------------------------------------

using Mierosoft.Win32; using System; using System.Drawing; using System.Windows.Forms;

elass DialogsWithRegistry: BetterFontAndColorDialogs {

eonst string strRegKey = "Software\\ProgrammingWindowsWithCSharp\\DialogsWithRegistry";

elass DialogsWithRegistry: BetterFontAndColorDialogs {

eonst string strRegKey = "Software\\ProgrammingWindowsWithCSharp\\DialogsWithRegistry";

eonst

string

strFontFaee =

"FontFaee";

eonst

string

strFontSize =

"FontSize";

eonst

string

strFontStyle =

"FontStyle";

eonst

string

strForeColor =

"ForeColor";

eonst

string

strBaekColor =

"BaekColor";

eonst

string

strCustomClr =

"CustomColor

publie new statie void Main() {

Applieation.Run(new DialogsWithRegistryO);

publie new statie void Main() {

Applieation.Run(new DialogsWithRegistryO);

public DialogsWithRegistryO {

Text = "Font and Color Dialogs with Registry";

RegistryKey regkey = Registry.CurrentUser.OpenSubKey(strRegKey);

Font = new Font((string) regkey.GetValue(strFontFace), float.Parse(

(string) regkey.GetValue(strFontSize)), (FontStyle) regkey.GetValue(strFontStyle));

ForeColor = Color.FromArgb(

(int) regkey.GetValue(strForeColor));

BackColor = Color.FromArgb(

(int) regkey.GetValue(strBackColor));

aiColors[i] = (int) regkey.GetValue(strCustomClr + i);

clrdlg.CustomColors = aiColors;

regkey.Close();

protected override void OnClosed(EventArgs ea) {

RegistryKey regkey =

Registry.CurrentUser.OpenSubKey(strRegKey, true); if (regkey == null)

regkey = Registry.CurrentUser.CreateSubKey(strRegKey);

regkey.SetValue(strFontFace, regkey.SetValue(strFontSize, regkey.SetValue(strFontStyle, regkey.SetValue(strForeColor, regkey.SetValue(strBackColor,

Font.Name);

Font.SizelnPoints. ToStringO); (int) Font.Style); ForeColor.ToArgb() ) ; BackColor.ToArgb());

regkey.SetValue(strCustomClr + i, clrdlg.CustomColors[i]);

regkey.Close();

Let's look at the override of the OnClosed method first. OnClosed is called when the form has been closed. That's a good time for the program to write information to the registry. If the OpenSubKey call returns null, the program must be running for the first time, so it calls CreateSubKey to create the registry key. Each SetValue call stores either an integer or a string in the registry. For the form's Font property, three values must be stored: the Name, SizelnPoints, and Style properties. The SizelnPoints property of Font is a float, so that value is converted to a string representation with ToString. The ToArgb method of the Color class converts Color objects into integers.

Also take note of the SetValue call in the for loop that's used to store the custom colors. The value name is strCustomClr + i which creates names of CustomColorO, CustomColorl, through CustomColor15.

The values are loaded from the registry in the program's constructor. The form's font is re-created using the face name, point size, and style values. The point size has to be converted from a string back to a float using the static Parse method of the Single class. The static Color.FromArgb method converts the stored integers back into Color objects.

Because implementing registry support requires working with two blocks of code, registry read and write code can be difficult to debug. The best approach is to get all the SetValue calls working first. Monitor your progress with the Registry Editor. (F5 refreshes the display.) The Registry Editor also lets you delete an entire key, so you can test how well your program re-creates the registry entries from scratch. When you get all the SetValue calls working, then code the GetValue calls.

Was this article helpful?

0 0

Post a comment