Working with Windows Registry in Delphi

How to Read or Write data in Windows Registry by using Delphi ?

What is Windows Registry? a small introduction.
Registry is a simple hierarchical database that can be used to store Application or User related data in Tree structure. Windows Operating System already uses Registry to store different settings and User related data. It stores data in Root, Key and Value pattern.
Root - There are seven predefined root keys, traditionally named according to their constant handles defined in the Win32 API, or by synonymous abbreviations (depending on applications):
HKEY_LOCAL_MACHINE
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER 
HKEY_USERS 
Key – Variable name
Value – Variable value
The Registry "database" is stored as a binary file. To find it, run regedit.exe (Windows registry editor utility) in your Windows directory. 
For more about Windows Registry please visit following link…
https://support.microsoft.com/en-us/kb/256986

How to access Windows Registry from Delphi?
In Delphi we generally access Windows Registry to store Application and User related data like storing form position, User settings etc. Delphi provides TRegistry or TRegistryIniFile class that can be used to read/write Registry data.
TRegistry - TRegistry class provides generic encapsulation of Registry API to read/write data in Window Registry.
TRegistryIniFile - TRegistryInifile provides interface of the TInifile class to read/write data in Windows Registry. In case to make portability our Application with INI based and Registry based version we use TRegistryIniFile.
TRegIniFile - Same as like TRegistryIniFile. This only acts as helper class of TRegistryIniFile class. 
For more about Delphi class helper visit...
http://docwiki.embarcadero.com/RADStudio/XE8/en/Class_and_Record_Helpers_(Delphi)

Using TRegistry
The reading of data from the registry is illustrated with an example. We will create a new form which will remember its previous location on the screen. The location is determined by the Top and Left properties of the form. In addition to these, we will read and store the Height and Width properties of the form

const
  cKey = 'SOFTWARE\Test_Company\Test_Application';
  // key where item values will be stored and read
procedure TRememberForm.FormCreate(Sender:
  TObject);
var
  lReg: TRegistry;
  getInt: integer;
begin
  inherited;
  // general purpose:
  // read latest Left, Top, Width and Height
  lReg := TRegistry.Create;
  // create registry object
  lReg.RootKey := HKEY_CURRENT_USER;
  // set root to current user root,
  // to ensure different users on this
  // machine have their own setting
  lReg.OpenKey(cKey, True);
  // Open key where we will read items
  if lReg.ValueExists(self.name +
    '.Left') then // check if
    value for item formname.left exists
    begin
      getint := lReg.ReadInteger(self.name
        + '.Left'); // Read left position of actual form
      if getint > 0 then
        self.Left := getint;
    end;
  if lReg.ValueExists(self.name +
    '.Top') then
  begin
    getint := lReg.ReadInteger(self.name + '.Top');
    if getint > 0 then
      self.Top := getint;
  end;
  if lReg.ValueExists(self.name + '.Width') then
  begin
    getint := lReg.ReadInteger(self.name + '.Width');
    if getint > 0 then
      self.Width := getint;
  end;
  if lReg.ValueExists(self.name + '.Height') then
  begin
    getint := lReg.ReadInteger(self.name + '.Height');
    if getint > 0 then
      self.Height := getint;
  end;
  // Close and free
  lReg.CloseKey;
  lReg.Free;

end;

The FormDestroy event is a good moment to write the data to the registry. The code is a lot shorter:  
procedure TRememberForm.FormDestroy(Sender: TObject);
var
  lReg: TRegistry;
begin
  // open registry, set root and key
  lReg := TRegistry.Create;
  lReg.RootKey := HKEY_CURRENT_USER;
  lReg.OpenKey(cKey, True);
  // write last Left, Top, Width and Height
  lReg.WriteInteger(self.name + '.Left', self.Left);
  lReg.WriteInteger(self.name + '.Top', self.Top);
  lReg.WriteInteger(self.name + '.Width', self.Width);
  lReg.WriteInteger(self.name + '.Height', self.Height);
  // close all
  lReg.CloseKey;
  lReg.Free;
  inherited;
end;
As with reading data, the same applies with writing data. You can easily write boolean, datetimes, floats, strings and binary data.

If an Application runs under 32 bit OS then it works fine but if runs on 64bit only the 32bit apps are recorded because of the Wow6432 node redirection. So in this case we have to create TRegistry object like follow..
//to access 64bit OS registry data create Tregistry object as follow//
Registry := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY);

Using TRegistryIniFile

Read form data from Registry on load
procedure TForm1.FormCreate(Sender: TObject); 
var Reg: TRegistryIniFile; 
begin 
Reg := TRegistryIniFile.Create('Software\' + Application.Title'); 
try 
Top     := Reg.ReadInteger(Name, 'Top', Top );
Left    := Reg.ReadInteger(Name, 'Left', Left );
Width   := Reg.ReadInteger(Name, 'Width', Width );
Height  := Reg.ReadInteger(Name, 'Height', Height );
Caption := Reg.ReadString (Name, 'Caption', Caption);
finally 
Reg.Free; 
end; 
end;

Write form data to Registry on destroy
procedure TForm1.FormDestroy(Sender: TObject); 
var Reg: TRegistryIniFile; 
begin 
Reg := TRegistryIniFile.Create('Software\' + Application.Title'); 
try 
Reg.WriteInteger (Name, 'Top', Top);
Reg.WriteInteger (Name, 'Left', Left);
Reg.WriteInteger (Name, 'Width', Width);
Reg.WriteInteger (Name, 'Height', Height);
Reg.WriteString  (Name, 'Caption', Caption);
finally 
Reg.Free; 
end; 
inherited;

end;

Limitations and points need to care when using registry to store data.
There are a few limitations which we haven't discussed. First, The registry is not meant a database for storing vast quantities of data. It is meant for storing initialization and configuration data. Anything over 2Kb had better be stored in a separate file. If you wish, you can mention the corresponding file location in the registry. Then WriteBinary is especially useful for storing recordtypes. Using a record type saves you typing code, and it can be written to and read from the registry with 1 statement, saving both time and storage. And a large registry might slow down all applications.




Comments

Popular posts from this blog

ShellExecute in Delphi

How to send Email in Delphi?

Variants in Delphi. Use of Variant Array. How to check a Variant is unassigned or empty or clear ?