понедельник, 28 июля 2008 г.

Сохранение данных в реестр windows.

На прошлом уроке мы с вами рассмотрели методику записи и чтения пользовательских данных и данных состояния компонентов в ini файл. Эта методика хранения параметров программы является устаревшей. Рекомендуется для этих целей использовать реестр.

Для начала краткая информация о реестре. Проще говоря, реестр windows, эта огромная база данных, хранящая в себе всевозможные пользовательские и системные данные. Установленное оборудование, драйвера, установленные шрифты, установленные принтеры и многое другое записано в соответствующих разделах.
Как же все-таки увидеть данные реестра? Очень просто. Надо нажать на кнопку "Пуск", выбрать пункт "Выполнить" и ввести название программы REGEDIT, которая отображает реестр для чтения и редактирования. Эта программа находится в каталоге windows. Помните, что некорректное изменение некоторых системных ключей в реестре может привести к постоянным сбоям в системе, может привести даже к полному краху операционной системы, поэтому изменения и удаление следует производить очень осторожно.
Внешний вид этой программы состоит из двух панелей. Левая древовидная и правая, в которой отображаются параметры ключей. Ключ - это элемент реестра, который может содержать некоторые данные или содержать другие ключи. Это древовидная структура, которая хранит в себе вложенные параметры, объединенные общей тематикой. Не буду рассказывать назначение отдельных ключей, это может занять не одну книгу, скажу только, что программы, которые работают с реестром в качестве ini файла, автоматически записывают и читают данные из глобального ключа HKEY_CURRENT_USER. Он же дублируется в ключе HKEY_USERS\ИМЯ_ТЕКУЩЕГО_ПОЛЬЗОВАТЕЛЯ.
Дальше рассмотрим запись и чтение данных. Тут методика аналогична работе с ini файлами.
Для начала в разделе подключаемых модулей Uses нужно указать модуль Registry, который необходим для использования команд работы с реестром.
Объявление реестровой переменной

Var ПЕРЕМЕННАЯ:TRegIniFile;

Создание реестровой переменной, через которую будем читать и писать данные

ПЕРЕМЕННАЯ:=TRegIniFile.Create(НАЗВАНИЕ_КЛЮЧА);

Пример объявления, создания и удаления.

procedure TForm1.FormShow(Sender: TObject);
Var RegIniFile:TRegIniFile;
// реестровая переменная
begin
RegIniFile:=TRegIniFile.Create('MySelfRegistryApplication');
// создание реестровой переменной
RegIniFile.Free;
// уничтожение вручную созданного объекта
end;


Подробно о командах чтения и записи.

Чтение и запись целочисленного значения, типа integer:

RegIniFile.ReadInteger(СЕКЦИЯ,ПАРАМЕТР,ЗНАЧЕНИЕ_ПО_УМОЛЧАНИЮ);
RegIniFile.WriteInteger(СЕКЦИЯ,ПАРАМЕТР,ЗНАЧЕНИЕ);


Дальше аналогично вышерассмотренной команде следует чтение и запись:
двоичного значения ReadBool и WriteBool;
строкового значения ReadString и WriteString;

Если необходимо сохранить данные не в отдельной секции, а в ключе, то вместо параметра СЕКЦИЯ необходимо указать пустую строку, или две кавычки ''.

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

RegIniFile.ValueExists(ПАРАМЕТР)

Эта команда является функцией, возвращающей истинно (true) или ложно (false), и ее можно использовать в паре с чтением определенного параметра. Например, чтение числа с плавающей точкой:

if RegIniFile.ValueExists('MyFloat') then // если данный параметр существует, то
Edit2.Text:=FloatToStr(RegIniFile.ReadFloat('MyFloat'));
// прочитать параметр

Пример.
В новом проекте помещаем в форму следующие компоненты:
· 2 компонента CheckBox
· компонент ComboBox, установите в свойстве Items некоторые строки.
· 2 компонента Edit
· компонент DateTimePicker (страница Win32 палитры компонентов)

Процедура OnShow для окна Form1

procedure TForm1.FormShow(Sender: TObject);
Var RegIniFile:TRegIniFile;
// реестровый объект
begin
RegIniFile:=TRegIniFile.Create('MySelfRegistryApplication');
// создание реестровой переменной
Form1.Left:=RegIniFile.ReadInteger('Form1','Form1Left',Form1.Left);
// левая граница окна
Form1.Top:=RegIniFile.ReadInteger('Form1','Form1Top',Form1.Top);
// верхняя граница окна
Form1.Height:=RegIniFile.ReadInteger('Form1','Form1Height',Form1.Height);
// высота окна
Form1.Width:=RegIniFile.ReadInteger('Form1','Form1Width',Form1.Width);
// ширина окна
// Восстановление состояния компонентов
CheckBox1.Checked:=RegIniFile.ReadBool('Form1','CheckBox1Checked',CheckBox1.Checked);
CheckBox2.Checked:=RegIniFile.ReadBool('Form1','CheckBox2Checked',CheckBox2.Checked);
ComboBox1.ItemIndex:=RegIniFile.ReadInteger('Form1','ComboBox1ItemIndex',ComboBox1.ItemIndex);
Edit1.Text:=RegIniFile.ReadString('Form1','Edit1Text',Edit1.Text);
if RegIniFile.ValueExists('MyFloat') then
// если такой параметр существует, то:
Edit2.Text:=FloatToStr(RegIniFile.ReadFloat('MyFloat'));
// чтение числа с запятой
if RegIniFile.ValueExists('MyDate') then
// если такой параметр существует, то:
DateTimePicker1.Date:=RegIniFile.ReadDate('MyDate');
// чтение даты

RegIniFile.Free;
// уничтожение вручную созданного объекта
end;


Процедура OnClose для окна Form1

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
Var RegIniFile:TRegIniFile;
begin
RegIniFile:=TRegIniFile.Create('MySelfRegistryApplication');
RegIniFile.WriteInteger('Form1','Form1Left',Form1.Left);
RegIniFile.WriteInteger('Form1','Form1Top',Form1.Top);
RegIniFile.WriteInteger('Form1','Form1Height',Form1.Height);
RegIniFile.WriteInteger('Form1','Form1Width',Form1.Width);
// Сохранение состояния компонентов
RegIniFile.WriteBool('Form1','CheckBox1Checked',CheckBox1.Checked);
RegIniFile.WriteBool('Form1','CheckBox2Checked',CheckBox2.Checked);
RegIniFile.WriteInteger('Form1','ComboBox1ItemIndex',ComboBox1.ItemIndex);
RegIniFile.WriteString('Form1','Edit1Text',Edit1.Text);

RegIniFile.WriteFloat('MyFloat',StrToFloat(Edit2.Text));
RegIniFile.WriteDate('MyDate',DateTimePicker1.Date);

RegIniFile.Free;
end;

Обратите внимание, что в этом примере для записи состояния компонента Edit2 используется преобразование строковой величины в число. Если в этом компоненте будут недопустимые символы, то при закрытии окна будет выдаваться ошибка. Для разделения дробной от целой части (запятая), используйте соответствующий символ, установленный в конфигурации windows как символ разделителя.

После запуска и закрытия этой программы можно запустить редактор реестра и просмотреть результат записи данных. Они находятся в ключе HKEY_CURRENT_USER, подключе MySelfRegistryApplication, как было указано в программе. Данные состояния окна, компонентов CheckBox1, CheckBox2 и Edit1 находятся в секции Form1, остальные данные: число в компоненте Edit2, дата в компоненте DateTimePicker1 находятся непосредственно в ключе MySelfRegistryApplication.
Посмотреть на параметры, записанные вышерассмотренной программой автоматически при закрытии, можно на двух рисунках. В первом рисунке вы видите данные даты и дробного числа, во втором рисунке вы видите содержание секции Form1. Эта секция является одновременно подключом ключа MySelfRegistryApplication.
Удаление того или иного параметра приведет к сбросу сохраняемой величины и при запуске программы будет установлено начальное значение по умолчанию. Удаление всего ключа MySelfRegistryApplication приведет к сбросу всех данных нашей программы. Удалить параметр или ключ в редакторе реестра можно кнопкой Del или выбрав соответствующий пункт из выпадающего меню по правой кнопке мышки.
Программное удаление параметра осуществляется командой
RegIniFile.DeleteKey(СЕКЦИЯ, ПАРАМЕТР);

Этот пример можно забрать по ссылке тут.

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


Некоторые команды для работы со строками

Вспомним, а для некоторых узнаем некоторые команды для работы со строками.
Строка является набором символов. Строковые переменные можно склеивать, разрезать, копировать, удалять символы.
Для склеивания нескольких строк можно воспользоваться знаком + как в арифметической операции сложения.
Копирование части строки в другую строку производится функцией Copy. Она возвращает результат копирования:

РЕЗУЛЬТАТ:=Copy(ИСХОДНАЯ_СТРОКА, ПЕРВЫЙ_СИМВОЛ, ДЛИНА_ЧАСТИ_СТРОКИ);

Удаления части в строке производится процедурой Delete:

Delete(СТРОКА,ПЕРВЫЙ_СИМВОЛ, ДЛИНА);

Для вставки части строки в другую применяем процедуру Insert

Insert(ВСТАВЛЯЕМАЯ_СТРОКА, РЕЗУЛЬТИРУЮЩАЯ_СТРОКА, НОМЕР_СИМВОЛА_ВСТАВКИ);

В любой момент можно узнать длину строки с помощью функции Length(СТРОКА), а установить длину строки можно процедурой SetLength(СТРОКА, НОВАЯ_ДЛИНА).

В pascal'е строковая переменная объявляется как тип String. Если объявляем такую переменную, значит мы будем ее использовать для работы со строками. Но в отличие от языка программирования pascal, в таких строках запрещен доступ к нулевому символу (в этом символе хранилось длина строки). Поскольку в операционной системе windows все строки имеют стандарт PChar (строки, заканчивающиеся символом #0), то тип String здесь оставлен для совместимости. Фактически длина строки String не ограничена 255 символами, как в pascal. Но применяя этот тип, вы незаметно для себя, применяете тип PChar. Все операции перевода одного типа в другой delphi производит автоматически.
Вот пример процедуры обработки строк.

procedure StringOper;
Var st1,st2,st3,st4:String;
// объявление строковых переменных
i:integer;
// целочисленная переменная
begin
st1:='это 1 строка';
st2:='это 2 строка';
st3:=st1+' '+st2;
// результат 'это 1 строка это 2 строка'
st4:=Copy(st3,1,5);
// копирование части строки. Результат 'это 1'
Delete(st4,1,4);
// удаление части строки. Результат '1'
Insert(' строка',st4,2);
// вставка части строки в строку st4. Результат '1 строка'
st4[1]:='2';
// изменение первого символа строки с 1 на 2
i:=Length(st4);
// определение длины строки i=8
SetLength(st4,7);
// установка новой длины строки. Результат '1 строк'
end;

Комментариев нет: