Sources
Delphi Russian Knowledge Base
DRKB - база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Использование реестра

01.01.2007
Алексей Федоров

Реестр - это центральное хранилище информации о параметрах системы и установленных программах. В версиях Windows до Windows 95 программисты сохраняли параметры программ либо в INI-файлах WIN.INI и SYSTEM.INI, либо в дополнительных INI-файлах. Хотя использование INI-файлов поддерживается и в Win32, Microsoft настоятельно рекомендует для хранения необходимых в работе программы параметров пользоваться реестром. Реестр представляет собой иерархическую базу данных, cостоящую из секций, подсекций и элементов. Каждая секция имеет свое назначение. Хранить данные о пользовательских программах Microsoft рекомендует в секции HKEY_CURRENT_USER и подсекции Software. В этой подсекции вы создаете подсекцию, идентифицирующую вашу программу или фирму, и уже внутри нее располагаете данные.

Модуль Registry

Для упрощения работы с регистратором в состав Delphi (начиная с версии 2.0) входит модуль REGISTRY, содержащий реализацию трех классов, - TRegistry, TRegistryIniFile и TRegIniFile.

Внимание! Чтобы использовать свойства и методы классов TRegistry, TRegistryIniFile и TRegIniFile, необходимо включить в список uses модуль Registry.

TRegIniFile

Собственно говоря, задача класса TRegIniFile - упростить перенос 16-битных программ в среду Windows 95. Методы этого класса эквивалентны методам класса TIniFile в 16-битной версии Delphi. Класс TRegIniFile позволяет обращаться к секции HKEY_CURRENT_USER, считывать и записывать строки (методы ReadString и WriteString), целочисленные значения (методы ReadInteger и WriteInteger), логические значения (методы ReadBool и WriteBool), секции (методы ReadSection, ReadSections и ReadSectionValues), удалять секции (метод EraseSection) и элементы (метод DeleteKey). Рассмотрим на примерах, как используются функции этого класса.

Microsoft рекомендует записывать данные, относящиеся к вашей программе, в подсекции секции HKEY_CURRENT_USER_Software. Предположим (не особенно фантазируя на эту тему), что ваша программа называется RegDemo, и данные для нее располагаются в секции Software\RegDemo. Ниже мы покажем, как поместить в регистратор строчные, целочисленные и логические данные, а затем считать их, - этих операций будет достаточно для того, чтобы сохранить в регистраторе параметры нашей программы, а затем считать их.

Прежде чем записать данные в определенную секцию, ее необходимо создать. Это происходит при вызове конструктора объекта TRegIniFile. В качестве параметра вы указываете название секции, и если таковой не существует, она создается:

RegFile := TRegIniFile.Create(SubKey);

После того как файл регистратора открыт (и создана определенная секция), мы можем записать данные. Поддерживаются три типа данных: целочисленные, логические и строчные данные. Для записи этих данных существуют методы WriteInteger, WriteBool и WriteString. В качестве параметров указываются:

Так, чтобы записать значение элемента MyIntVal в подсекции IntKey, следует выполнить код

RegFile.WriteInteger(IntKey, 'Int_Val', 32000);

а для того чтобы прочесть значение, необходимо вызвать метод ReadInteger (в качестве параметров указываются название подсекции, название элемента и значение по умолчанию):

RegFile.ReadInteger(IntKey, 'Int_Val', 0));

Для чтения логических и строчных данных используются соответственно методы ReadBool и ReadStr, а для их записи - методы WriteBool и WriteString.

Расссмотрим пример использования перечисленных выше методов класса TRegIniFile. Расположим в форме компонент Memo, две группы GroupBox и шесть кнопок - три в группе Write и три в группе Read. Нажатие каждой кнопки в группе Write приведет к записи соответствующего значения в реестр, нажатие каждой кнопки в группе Read - к чтению этого значения.

Ниже приведен исходный текст модуля, в котором содержатся обработчики нажатия кнопок, использующие методы класса TRegIniFile.

unit RDUnit;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, Registry;
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation{$R *.DFM}var
  RegFile: TRegIniFile;
const
  //Подсекция
  SubKey: string = 'Software\RegDemo';
  // Элемент для хранения логических данных
  BoolKey: string = 'BoolKey';
  // Элемент для хранения целочисленных данных
  IntKey: string = 'IntKey';
  // Элемент для хранения строчных данных
  StrKey: string = 'StrKey';

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Создать экземпляр класса
  RegFile := TRegIniFile.Create(SubKey);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Записать целочисленное значение
  RegFile.WriteInteger(IntKey, 'Value', 1998);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  // Записать булево значение
  RegFile.WriteBool(BoolKey, 'Value', True);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  // Записать строку
  RegFile.WriteString(StrKey, 'Value', 'Demo');
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  // Считать целочисленное значение
  Memo1.Lines.Add('Int Value = ' +
    IntToStr(RegFile.ReadInteger(IntKey, 'Value', 0)));
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  // Считать булево значение
  if RegFile.ReadBool(BoolKey, 'Value', False) then
    Memo1.Lines.Add('Bool Value = True')
  else
    Memo1.Lines.Add('Bool Value = False');
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  // Считать строку
  Memo1.Lines.Add(RegFile.ReadString(StrKey, 'Value', ''));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // Удалить секцию
  RegFile.EraseSection(SubKey);
  // Освободить память
  RegFile.Free;
end;
end.

На приведенном ниже рисунке показано, как выглядит созданная нами подсекция в редакторе REGEDIT.

Отметим, что рассмотренных выше функций вполне достаточно для того чтобы обеспечить минимальную функциональность приложения. Если же вам требуется читать и записывать данные из других секций реестра, вы можете воспользоваться методами класса TRegistry или (что мене удобно) непосредственно функциями Win32 API.

Класс TRegistry

Прежде чем рассмотреть пример использования свойств и методов класса TRegistry, давайте кратко перечислим их.

В следующей таблице перечислены свойства класса TRegistry.

+-------------+-----------------------------------+
| Свойство    | Описание                          |
+-------------+-----------------------------------+
| CurrentKey  | Позволяет узнать текущую          |
|             | подсекцию, в которой проводятся   |
|             | операции по чтению и записи. Для  |
|             | изменения подсекции следует       |
|             | использовать методы OpenKey и     |
|             | OpenKeyReadOnly                   |
+-------------+-----------------------------------+
| CurrentPath | Позволяет узнать полное название  |
|             | текущей подсекции                 |
+-------------+-----------------------------------+
| LazyWrite   | Задает способ обновления          |
|             | информации в реестре -            |
|             | непосредственно или после вызова  |
|             | метода CloseKey.                  |
+-------------+-----------------------------------+
| RootKey     | Задает корневую секцию в реестре. |
|             | По умолчанию установлено значение |
|             | HKEY_CURRENT_USER                 |
+-------------+-----------------------------------+

В следующей таблице перечислены методы класса TRegistry.

+-------------------+-----------------------------------+
| Метод             | Описание                          |
+-------------------+-----------------------------------+
| CloseKey          | Записывает внесенные изменения и  |
|                   | закрывает текущую подсекцию       |
+-------------------+-----------------------------------+
| Create            | Создает экземпляр класса          |
|                   | TRegistry и задает значение       |
|                   | корневой секции -                 |
|                   | HKEY_CURRENT_USER                 |
+-------------------+-----------------------------------+
| CreateKey         | Создает подсекцию                 |
+-------------------+-----------------------------------+
| DeleteKey         | Удаляет подсекцию                 |
+-------------------+-----------------------------------+
| DeleteValue       | Удаляет значение элемента         |
+-------------------+-----------------------------------+
| Destroy           | Уничтожает ранее созданный        |
|                   | экземпляр класса TRegistry        |
+-------------------+-----------------------------------+
| GetDataInfo       | Возвращает тип данных для         |
|                   | указанного элемента               |
+-------------------+-----------------------------------+
| GetDataSize       | Возвращает размер данных для      |
|                   | указанного элемента               |
+-------------------+-----------------------------------+
| GetDataType       | Возвращает тип данных для         |
|                   | указанного элемента               |
+-------------------+-----------------------------------+
| GetKeyInfo        | Возвращает информацию о текущем   |
|                   | элементе                          |
+-------------------+-----------------------------------+
| GetKeyNames       | Возвращает имена подсекций для    |
|                   | указанной секции                  |
+-------------------+-----------------------------------+
| GetValueNames     | Возвращает названия элементов для |
|                   | указанной подсекции               |
+-------------------+-----------------------------------+
| HasSubKeys        | Позволяет узнать, имеются ли      |
|                   | подсекции для указанной секции    |
+-------------------+-----------------------------------+
| KeyExists         | Позволяет узнать, существует ли   |
|                   | элемент                           |
+-------------------+-----------------------------------+
| LoadKey           | Создает новую подсекцию и         |
|                   | загружает в нее информацию из     |
|                   | указанного файла                  |
+-------------------+-----------------------------------+
| MoveKey           | Перемещает указанную подсекцию и  |
|                   | все вложенные подсекции в         |
|                   | заданное место                    |
+-------------------+-----------------------------------+
| OpenKey           | Открывает подсекцию               |
+-------------------+-----------------------------------+
| OpenKeyReadOnly   | Открывает подсекцию только для    |
|                   | чтения                            |
+-------------------+-----------------------------------+
| ReadBinaryData    | Считывает данные в бинарном       |
|                   | формате                           |
+-------------------+-----------------------------------+
| ReadBool          | Считывает данные в булевом        |
|                   | формате                           |
+-------------------+-----------------------------------+
| ReadCurrency      | Считывает данные в формате валюты |
+-------------------+-----------------------------------+
| ReadDate          | Считывает данные в формате даты   |
+-------------------+-----------------------------------+
| ReadDateTime      | Считывает данные в формате        |
|                   | "дата/время"                      |
+-------------------+-----------------------------------+
| ReadFloat         | Считывает данные в формате с      |
|                   | плавающей точкой                  |
+-------------------+-----------------------------------+
| ReadInteger       | Считывает данные в целочисленном  |
|                   | формате                           |
+-------------------+-----------------------------------+
| ReadString        | Считывает данные в строчном       |
|                   | формате                           |
+-------------------+-----------------------------------+
| ReadTime          | Считывает данные в формате        |
|                   | времени                           |
+-------------------+-----------------------------------+
| RegistryConnect   | Устанавливает соединение с        |
|                   | реестром на другом компьютере     |
+-------------------+-----------------------------------+
| RenameValue       | Переименовывает элемент           |
+-------------------+-----------------------------------+
| ReplaceKey        | Замещает значение элемента        |
|                   | значениями из файла               |
+-------------------+-----------------------------------+
| RestoreKey        | Восстанавливает значение элемента |
|                   | из файла                          |
+-------------------+-----------------------------------+
| SaveKey           | Сохраняет значение элемента в     |
|                   | файле                             |
+-------------------+-----------------------------------+
| UnLoadKey         | Удаляет подсекцию, загруженную    |
|                   | методом LoadKey                   |
+-------------------+-----------------------------------+
| ValueExists       | Позволяет узнать, существует ли   |
|                   | значение у элемента               |
+-------------------+-----------------------------------+
| WriteBinaryData   | Записывает данные в бинарном      |
|                   | формате                           |
+-------------------+-----------------------------------+
| WriteBool         | Записывает данные в булевом       |
|                   | формате                           |
+-------------------+-----------------------------------+
| WriteCurrency     | Записывает данные в формате       |
|                   | валюты                            |
+-------------------+-----------------------------------+
| WriteDate         | Записывает данные в формате даты  |
+-------------------+-----------------------------------+
| WriteDateTime     | Записывает данные в формате       |
|                   | "дата/время"                      |
+-------------------+-----------------------------------+
| WriteExpandString | Записывает данные в формате       |
|                   | "расширенной" строки              |
+-------------------+-----------------------------------+
| WriteFloat        | Записывает данные в формате с     |
|                   | плавающей точкой                  |
+-------------------+-----------------------------------+
| WriteInteger      | Записывает данные в целочисленном |
|                   | формате                           |
+-------------------+-----------------------------------+
| WriteString       | Записывает данные в строчном      |
|                   | формате                           |
+-------------------+-----------------------------------+
| WriteTime         | Записывает данные в формате       |
|                   | времени                           |
+-------------------+-----------------------------------+

После того как мы кратко познакомились со свойствами и методами класса TRegistry, давайте рассмотрим несколько примеров их использования.

Инициализация

Перед использованием свойств и методов класса TRegistry, необходимо создать экземпляр этого класса. Например:

var
  R: TRegistry;
  ...
  R := TRegistry.Create;

Задание корневой секции

Если вы собираетесь работать с секцией, отличной от HKEY_CURRENT_USER (это значение задается по умолчанию), то после инициализации вы должны изменить значение свойства RootKey.

Возможны следующие значения:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA
HKEY_CURRENT_CONFIG
HKEY_DYN_DATA

Например:

with R do
begin
  RootKey := HKEY_LOCAL_MACHINE;
  //
  // Продолжаем работу с реестром
  //
end;
Previous page:
Получить многострочные значения из реестра и преобразовать их в TStringList
Top:
DRKB
Next page:
Дополненный TRegistry, умеет работать с значениями типа REG_MULTI_SZ