Author: Ernesto De Spirito
How can I simply save and get data from the Windows Registry? The purpose of this
article is to introduce GetRegistryData and SetRegistryData as an alternative to
TRegistry, making it easy to read and write values from and to the Windows
Registry, allowing developers to access the registry in a practical way.
Answer:
What is the Registry?
It is where Windows stores many of its configuration options and also allows
applications to access this data as well as save their own data. If you want to
take a look at the registry, just execute the REGEDIT.EXE application located in
the Windows directory. Be careful not to change anything or you could end up
ruining your installation! Now, the data in the registry is stored in a tree
structure. There are many roots (many trees):
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA
HKEY_CURRENT_CONFIG
HKEY_DYN_DATA
Each root can have values and keys. The values are data stored under item names
(right panel of RegEdit). Keys can have values and other keys, forming a tree
structure (left panel of RegEdit).
For example, the tree HKEY_CURRENT_USER has many keys, like AppEvents, Control
Panel, Identities, Network, Software, etc. Each key may have sub-keys. For example,
Control Panel has some sub-keys, like Accessibility, Appearance, Colors, Cursors,
Desktop, International, etc. All keys have at least one value (the first value in
the right panel of RegEdit), which is the default value (the name of the value is
the empty string), not necessarily set. A key may have more values. For example,
let's see the key Control Panel\Colors under HKEY_CURRENT_USER. Appart from the
default value, it has values like ActiveBorder, ActiveTitle, AppWorkspace,
Background, etc. In turn, each "value" has a "data" (the actual value, sort to
speak). For example, the data of the value ActiveTitle would be "0 0 128" (may be
different if you are not using the standard Windows colors).
TRegistry
Before getting into GetRegistryData and SetRegistryData, let's see how we would
accomplish the same tasks the hard way, using TRegistry.
The TRegistry class is declared in the Registry unit, so you will have to add this
unit to the Uses clause of the unit or program where you want to use it. To access
a value in the registry, first you should create an object of this class, assign
the root to its RootKey property (the values are defined in the Windows unit) and
then try to open a key with the OpenKey function method, which will return True if
successful. Then you can read (with the ReadXxxx functions) or write (with the
WriteXxxx procedures) the values of the open key and, after that, you should close
the key with CloseKey. When you are done with the registry, you should free the
registry object you created. Let's see an example of how to obtain the name of the
processor in our computer:
1 procedure TForm1.Button1Click(Sender: TObject);
2 var
3 Reg: TRegistry;
4 begin
5 Reg := TRegistry.Create;
6 Reg.RootKey := HKEY_LOCAL_MACHINE;
7 if Reg.OpenKey('\Hardware\Description\System'
8 + '\CentralProcessor\0', False) then
9 begin
10 ShowMessage(Reg.ReadString('Identifier'));
11 Reg.CloseKey;
12 end; // if
13 Reg.Free;
14 end;
You can see another example in the article Determining the associated application.
Of course, there are many more things you can do with the registry, like creating
and deleting keys and values...
The TRegistryIniFile class makes it simpler for applications to write and read
their configuration information to and from the registry, while TRegistry operates
at a lower level.
GetRegistryData
To simplify reading a data value from the registry you can use the following
function that can read any data type from the registry and returns it as a variant
(string or integer). The function performs exception handling.
15 uses Registry;
16
17 function GetRegistryData(RootKey: HKEY; Key,
18 Value: string): variant;
19 var
20 Reg: TRegistry;
21 RegDataType: TRegDataType;
22 DataSize, Len: integer;
23 s: string;
24 label
25 cantread;
26 begin
27 Reg := nil;
28 try
29 Reg := TRegistry.Create(KEY_QUERY_VALUE);
30 Reg.RootKey := RootKey;
31 if Reg.OpenKeyReadOnly(Key) then
32 begin
33 try
34 RegDataType := Reg.GetDataType(Value);
35 if (RegDataType = rdString) or
36 (RegDataType = rdExpandString) then
37 Result := Reg.ReadString(Value)
38 else if RegDataType = rdInteger then
39 Result := Reg.ReadInteger(Value)
40 else if RegDataType = rdBinary then
41 begin
42 DataSize := Reg.GetDataSize(Value);
43 if DataSize = -1 then
44 raise Exception.Create(SysErrorMessage(ERROR_CANTREAD));
45 SetLength(s, DataSize);
46 Len := Reg.ReadBinaryData(Value, PChar(s)^, DataSize);
47 if Len <> DataSize then
48 raise Exception.Create(SysErrorMessage(ERROR_CANTREAD));
49 Result := s;
50 end
51 else
52 raise Exception.Create(SysErrorMessage(ERROR_CANTREAD));
53 except
54 s := ''; // Deallocates memory if allocated
55 Reg.CloseKey;
56 raise;
57 end;
58 Reg.CloseKey;
59 end
60 else
61 raise Exception.Create(SysErrorMessage(GetLastError));
62 except
63 Reg.Free;
64 raise;
65 end;
66 Reg.Free;
67 end;
68
69 //Sample Call
70
71 ShowMessage(GetRegistryData(HKEY_LOCAL_MACHINE,
72 '\Hardware\Description\System\CentralProcessor\0', 'Identifier'));
SetRegistryData
To simplify writing a data value to the registry you can use the following
procedure that can write any data type to the registry. The procedure performs
exception handling.
73 uses Registry;
74
75 procedure SetRegistryData(RootKey: HKEY; Key, Value: string;
76 RegDataType: TRegDataType; Data: variant);
77 var
78 Reg: TRegistry;
79 s: string;
80 begin
81 Reg := nil;
82 try
83 Reg := TRegistry.Create(KEY_WRITE);
84 Reg.RootKey := RootKey;
85 if Reg.OpenKey(Key, True) then
86 begin
87 try
88 if RegDataType = rdUnknown then
89 RegDataType := Reg.GetDataType(Value);
90 if RegDataType = rdString then
91 Reg.WriteString(Value, Data)
92 else if RegDataType = rdExpandString then
93 Reg.WriteExpandString(Value, Data)
94 else if RegDataType = rdInteger then
95 Reg.WriteInteger(Value, Data)
96 else if RegDataType = rdBinary then
97 begin
98 s := Data;
99 Reg.WriteBinaryData(Value, PChar(s)^, Length(s));
100 end
101 else
102 raise Exception.Create(SysErrorMessage(ERROR_CANTWRITE));
103 except
104 Reg.CloseKey;
105 raise;
106 end;
107 Reg.CloseKey;
108 end
109 else
110 raise Exception.Create(SysErrorMessage(GetLastError));
111 except
112 Reg.Free;
113 raise;
114 end;
115 Reg.Free;
116 end;
117
118 //Sample Call
119
120 SetRegistryData(HKEY_LOCAL_MACHINE,
121 '\Software\Microsoft\Windows\CurrentVersion',
122 'RegisteredOrganization', rdString, 'Latium Software');
You can find another example of SetRegistryData in my article Making an application
run automatically when Windows starts.
Component Download: http://www.latiumsoftware.com/download/delphi-2.zip
Copyright (c) 2001 Ernesto De Spiritomailto:edspirito@latiumsoftware.com
Visit: http://www.latiumsoftware.com/delphi-newsletter.php
|