Лекция № 16

Тема:"Создание настраиваемых форм. Работа с реестром Windows"

 

План

1. Понятие и структура реестра

2. Работа с реестром

3. Запись данных в реестр

4. Чтение данных из реестра

5. Удаление данных из реестра

6. Особенности работы с несколькими ветками реестра

 

1. Понятие и структура реестра

Раньше, в Windows 3.x информация о конфигурации и настройке приложения хранились в .INI файлах. Но для того чтобы упорядочить процессы установки и удаления программ, начиная с Windows 95 Microsoft требует, чтобы вся информация о конфигурации системы хранилась в системном реестре. Реестр (Registry) – это база данных для хранения информации о системной конфигурации аппаратуры, о Windows и о приложениях Windows. Почти все, что в Windows 3.x находилось в файлах .INI, перенесенное в реестр. Реестр имеет иерархическую структуру, которая, содержит много уровней разделов, веток и параметров. Информация хранится в виде иерархического дерева, каждый узел которого называется разделом. Раздел может содержать ветки и значения параметров.

Реестр делит все свои данные на две категории: те, что характеризуют компьютер, и те, что характеризуют пользователя. Характеристики компьютера содержат в себе все, связанное с техническими средствами, а также с установленными приложениями и их конфигурацией. Характеристики пользователя содержат в себе установки по умолчанию для экрана, пользовательские конфигурации, информацию об выбранных пользователем принтерах, установках сети и т.п.

Все ветки относятся к пяти основным разделам реестра. Три из них определяют характеристики компьютера:

 

HKEY_CLASSES_ROOT

Информация об OLE, Drag&Drop, клавишах быстрого доступа и пользовательском интерфейсе Windows

HKEY_LОСAL_MАСHINE

Информация о компьютере, включая конфигурацию установленной аппаратуры и программного обеспечения

HKEY_CURRENT_CONFIG

Информация о текущем оборудовании

 

Два раздела верхнего уровня определяют характеристики пользователя:

 

HKEY_CURRENT_USER

Информация о пользователе, зарегистрированном в текущий момент

HKEY_USERS

Информация о пользователях, включая установки экрана и приложений

 

Реестр хранится в файле SYSTEM.DAT в каталоге Windows. Просмотр и редактирования реестра Windows осуществляется редактором реестра Regedit.exe. Будьте предельно внимательны при работе с реестром. Иначе ваши эксперименты могут закончится плачевно вплоть до необходимости переустанавливать Windows.

 

2. Доступ к реестру

Для работы с реестром в Delphi существует класс TRegistry, описанный в модуле Registry. Если вы создаете в приложении объект класса TRegistry для работы с реестром, не забудьте подключить данный модуль:  

 

uses . . ., Registry;

 

Для записи данных в реестр или чтения данных из реестра в программе должна быть описанная переменная типу TRegistry, и этой переменной должен быть присвоен новый экземпляр объекта TRegistry, который создается методом Create. Например:

 

uses . . ., Registry;

. . .

var reg:TRegistry;

. . .

begin

    . . .

    reg:=TRegistry.Create;

    . . .

end;

 

Все ветки в объекте класса TRegistry создаются как ветки определенного корневого раздела, записанного в свойстве RootKey. По умолчанию RootKey = HKEY_CURRENT_USER. В каждый момент объект типа TRegistry имеет доступ только до одному текущему разделу в иерархии, которая начинается с ключа RootKey. Если нужно работать с определенным корневым разделом, то после создания нового экземпляра объекта TRegistry нужно сделать активным соответствующий раздел реестра. Например, оператор

 

reg.RootKey:=HKEY_Local_Machine;

 

делает активным раздел HKEY_LOCAL_MACHINE и все последующие действия будут проводиться в этом разделе.

После задания текущего корневого раздела нужно открыть в ней соответствующую ветку для чтения или записи. Для этого использую метод

 

reg.OpenKey('Путь к ветке реестра', CanCreate);

 

Этот метод открывает указанную ветку реестра, делая ее текущей для работы. Если путь – пустая строка, то текущим делается корневой ключ, указанный свойством RootKey. Параметр CanCreate указывает, должна ли создаваться указанная ветка, если ее нет в реестре (если True – то ветка будет создана автоматически). Создаваемая ветка хранится в реестре при следующих запусках системы.

 

3. Запись данных в реестр

После открытия ветки в нее можно записывать данные разными методами в зависимости от типа информации:

 

reg.WriteString('Name', 'Value'); //запись текстового параметра

reg.WriteInteger('Name', Value); //запись целого параметра

reg.WriteFloat('Name', Value); //запись вещественного параметра

reg.WriteBool('Name', Value); //запись логического параметра (true или false)

reg.WriteDate('Name', Value); //запись даты

reg.WriteTime('Name', Value); //запись времени

 

Все они заносят значение "Value" в параметр с именем "Name".

Например, пусть на форме имеется флажок Checkbox и два переключателя RadioButton1 и RadioButton2. Сохраним размер и положение формы, а также состояние флажка и переключателей в разделе реестра HKEY_local_Machine, в ветке "Software\Primer".

Для этого в событии OnClose формы напишем код:

 

uses . . ., Registry;

. . .

procedure TForm1.FormClose(Sender: TObject; Var Action: TCloseAction);

//описываем переменную для хранения экземпляра объекта TRegistry

Var reg:TRegistry;

begin

    //создаем новый экземпляр объекта TRegistry

    reg:=TRegistry.Create;

    //устанавливаем текущий корневой раздел реестра

    reg.RootKey:=HKEY_Local_Machine;

    //открываем ветку (если ее нет, то она будет создана

    reg.OpenKey('Software\Primer',true);

    //записываем ширину формы в параметр "Width"

    reg.WriteInteger('Width',Width);

    //записываем высоту формы в параметр "Height"

    reg.WriteInteger('Height',Height);

    //записываем положение формы по горизонтали в параметр "Х"

    reg.writeinteger('Х',Left);

    //записываем положение формы по вертикали в параметр "Y"

    reg.WriteInteger('Y',Top);

    //записываем состояние флажка в параметр "Check"

    reg.WriteBool('Check',Checkbox1.Checked);

    //записываем номер включенного переключателя в параметр "Radio"

    //если включен первый флажок

    if RadioButton1.Checked then

        // записываем в реестр его номер

        reg.WriteInteger('Radio',1)

    //иначе, записываем в реестр номер второго переключателя

    else

        reg.WriteInteger('Radio',2);

        //удаляем экземпляр класса их памяти

    reg.Free;

end;

 

4. Чтение данных из реестра

Для чтения данных из реестра также существуют разные методы для разных типов данных:

 

reg.ReadString('Name'); //чтение текстового параметра

reg.ReadInteger('Name'); //чтение целого параметра

reg.ReadFloat('Name'); //чтение вещественного параметра

reg.ReadBool('Name'); //чтение логического параметра

reg.ReadDate('Name'); //чтение даты

reg.ReadTime('Name'); //чтение времени

 

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

 

reg.KeyExists ('Путь к ветке'); //проверяет наличие ветки в реестре

reg.ValueExists ('Name'); //проверяет наличие ключа в реестре

 

Например, при открытии формы нужно прочитать из реестра сохраненные раньше параметры и отобразить форму в соответствующем виде. Для этого в событии OnCreate формы напишем код:

 

uses . . ., Registry;

. . .

procedure TForm1.FormCreate(Sender: TObject);

//описываем переменную для хранения экземпляра объекта TRegistry

var reg:TRegistry;

begin

    //создаем новый экземпляр объекта TRegistry

    reg:=TRegistry.Create;

    //устанавливаем активным нужен раздел  реестра

    reg.RootKey:=HKEY_Local_Machine;

    //если нужной ветки в реестре нет

    if not reg.KeyExists('Software\Primer') then

        //завершаем работу

        Exit;

    //если параметр "Width" в ветке существует

    if reg.ValueExists('Width') then

        // считываем его значение и применяем к свойству формы

        Width:=reg.ReadInteger('Width');

 

    //если параметр "Height" в ветке существует

    if reg.valueexists('Height') then

        // считываем его значение и применяем к свойству формы

        Height:=reg.ReadInteger('Height');

 

    //если параметр "X" в ветке существует

    if reg.valueexists('Left') then

        // считываем его значение и применяем к свойству формы

        Left:=reg.ReadInteger('X');

 

    //если параметр "Y" в ветке существует

    if reg.ValueExists('Top') then

        // считываем его значение и применяем к свойству формы

        Top:=reg.ReadInteger('Y');

 

    //если параметр "Check" в ветке существует

    if reg.ValueExists('Check') then

        // считываем его значение и применяем к свойству флажка

        Checkbox1.Checked:=reg.ReadBool('Check');

 

    //если параметр "Radio" в ветке существует

    if reg.valueexists('Radio') then

        // считываем его значение и проверяем, чему он равен

        if reg.ReadInteger('Radio')=1 then

            //если параметр равен 1, то включаем первый переключатель

            RadioButton1.Checked:=true

        //иначе, включаем второй переключатель

        else

            Radiobutton2.Checked:=true;

    //удаляем экземпляр класса из памяти

    Reg.Free;

end;

5. Удаление данных из реестра

Для удаления данных из реестра существуют методы:

 

reg.DeleteKey('Путь к ветке'); //удаление ветки из реестра

reg.DeleteValue('Name'); //удаление значения из реестра

 

Перед вызовом любого метода удаления нужно обязательно проверять наличие удаляемого элемента в реестре. Если такого элемента в реестре не окажется, то программа будет выдавать сообщение об ошибке.

Например, фрагмент кода

 

uses . . ., Registry;

. . .

var reg:TRegistry;

. . .

    reg:=TRegistry.Create;

    reg.RootKey:=HKEY_Local_Machine;

    if reg.KeyExists('software\primer' then

        reg.DeleteKey('software\primer');

. . .

 

удаляет из раздела реестра HKEY_LOCAL_MACHINE ветку "Software\Primer".

 

А фрагмент кода:

 

uses . . ., Registry;

. . .

var reg:TRegistry;

. . .

    reg:=TRegistry.Create;

    reg.RootKey:=HKEY_Local_Machine;

    if reg.KeyExists('software\primer') then

    begin

        reg.OpenKey('software\primer',true);

        if reg.ValueExists('Width') then

        reg.DeleteValue('Width');

    end;

. . .

удаляет из раздела реестра HKEY_LOCAL_MACHINE параметр "Width", расположенный в ветке "Software\Primer".

 

6. Особенности работы с несколькими ветвями реестра

Если в программе нужно записать или прочитать параметры из разных веток реестра в пределах одного раздела, то экземпляр очередной ветвей после обработки нужно закрыть методом CloseKey, а потом открыТЬ следующую ветку.

Например:

. . .

var reg:TRegistry;

. . .

begin

    . . .

    reg:=TRegisrty.Create;

    reg:=HKEY_Current_User;

    //открываем первую ветку

    reg.OpenKey('Путь к первой ветке', true);

    // команды чтения или записи параметров текущей ветки

    //закрываем первую ветку

    reg.CloseKey;

 

    //работаем со следующей ветвями

    //открываем вторую ветку

    reg.OpenKey('Путь ко второй ветке', true);

    // команды чтения или записи параметров текущей ветки

    //удаляем экземпляр ветки

    reg.Free;

end;

 

 Если нужно в одном сеансе работать с разными разделами реестра, то нужно сначала закрыть ветку, а затем задать имя нового раздела. Например:

. . .

var reg:TRegistry;

. . .

begin

    . . .

    reg:=TRegisrty.Create;

    //задаем первый раздел реестра

    reg:=HKEY_Current_User;

    //открываем ветку в первом разделе

    reg.OpenKey('Путь к ветке реестра', true);

    // команды чтения или записи параметров текущей ветки

    //закрываем ветку

    reg.CloseKey;

 

    //работаем со следующим разделом

    //задаем второй раздел реестра

    reg:=HKEY_Local_Machine;

    //открываем ветку во втором разделе

    reg.OpenKey('Путь к ветке реестра', true);

    // команды чтения или записи параметров текущей ветвей

    //удаляем экземпляр ветки

    reg.Free;

end;

Вопросы для самоконтроля

 

1. Дайте характеристику реестру Windows.

2. Какие разделы реестра вы знаете?

3. Какой модуль надо подключить для работы с реестром?

4. Как открыть нужный раздел и  ветку реестра?

5. Опишите стандартные действия, которые выполняют при работе с реестром

6. Приведите команды записи данных в реестр.

7. Приведите команды чтения данных из реестра.

8. Как проверить наличие ветки в реестре?

9. Как проверить наличие параметра в реестре?

10. Приведите команды удаления данных из реестра

11. Как в одном сеансе обработать несколько разделов или веток реестра?