Лекция № 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. Как в одном сеансе обработать несколько разделов или веток реестра?