| |
|
|||||||
|---|---|---|---|---|---|---|---|---|
Сохранение настроек в реестр |
||||||||
|
Лень движет прогресс! Это я к тому, что чем больше я ленюсь набирать тексты программ, тем больше я придумываю всяких инструментов, чтобы облегчить себе труд. На этот раз я изобрел (быть может велосипед, но САМ!) компонент, который свои свойства, объявленные в разделе published, сохраняет в реестре, где укажет ему пользователь. Как с ним работать? Как класс утроен? type
TConfiguration = class(TComponent)
private
FRoot: Cardinal;
FKey: string;
public
constructor Create(AOwner: TComponent;
ARoot: Cardinal; AKey: string); reintroduce;
destructor Destroy; override;
procedure Save; virtual;
procedure Load; virtual;
property Root: Cardinal read FRoot;
property Key: string read FKey;
published
end;
В конструктор Create передаете объект (AOwner), который будет отвечать за уничтожение экземпляра, передаете корневой раздел реестра (к примеру, HKEY_CURRENT_USER), и ключ, где должны находиться данные. Так как класс TConfiguration является производным от TComponent, то он уже имеет два published-свойства: Name и Tag. Метод Save производит сохранение данных в реестр. Если соответствующие ключи отсутствуют, то они будут созданы автоматически. Его реализация выглядит следующим образом: procedure TConfiguration.Save;
var
PropList: PPropList;
PropCount, i: Integer;
reg: TRegistry;
begin
PropCount := GetTypeData(ClassInfo).PropCount;
GetMem(PropList, SizeOf(PPropInfo)*PropCount);
reg := TRegistry.Create;
try
reg.RootKey := Root;
PropCount := GetPropList(ClassInfo, [tkInteger,
tkChar, tkFloat, tkLString, tkInt64],PropList);
for i:=0 to PropCount - 1 do
begin
if (PropList[i].PropType^^.Kind = tkInteger)
or (PropList[i].PropType^^.Kind = tkInt64)
or (PropList[i].PropType^^.Kind = tkFloat) then
begin
reg.OpenKey(Key, True);
reg.WriteString(PropList[i].Name,
FloatToStr(GetPropValue(Self,PropList[i].Name)));
reg.CloseKey;
Continue;
end;
if (PropList[i].PropType^^.Kind = tkLString)
or (PropList[i].PropType^^.Kind = tkChar) then
begin
reg.OpenKey(Key, True);
reg.WriteString(PropList[i].Name,
GetPropValue(Self,PropList[i].Name));
reg.CloseKey;
Continue;
end;
{------- Другие типы данных -------}
end;
finally
FreeMem(PropList);
reg.Free;
end;
end;
Чтение данных из реестра производится с помощью метода Load. Если нет в реестре сохраненных данных, то в свойства будут загружены нулевые значения (для строк - пустые строки). Выглядит он следующим образом: procedure TConfiguration.Load;
var
PropList: PPropList;
PropCount, i: Integer;
reg: TRegistry;
val: String;
begin
// получаем общее количество свойств
PropCount := GetTypeData(ClassInfo).PropCount;
// резервируем память
GetMem(PropList, SizeOf(PPropInfo)*PropCount);
// создаем объект реестра
reg := TRegistry.Create;
try
// устанавливаем корневой каталог
reg.RootKey := Root;
// получаем кол-во отфильтрованных свойств
PropCount := GetPropList(ClassInfo,
[tkInteger, tkChar, tkFloat, tkLString, tkInt64], PropList);
// перебираем их по очереди
for i:=0 to PropCount - 1 do
begin
// если числовой тип
if (PropList[i].PropType^^.Kind = tkInteger)
or (PropList[i].PropType^^.Kind = tkInt64)
or (PropList[i].PropType^^.Kind = tkFloat) then
begin
// открываем (создаем) ключ
reg.OpenKey(Key, True);
// пытаемся читать из реестра
val := reg.ReadString(PropList[i].Name);
//если удалось, то пишем значение в свойство
if val <> '' then
SetPropValue(Self,PropList[i].Name, StrToFloatDef(val,0));
// зарываем ключ
reg.CloseKey;
Continue;
end;
// Если строковой тип
if (PropList[i].PropType^^.Kind = tkLString)
or (PropList[i].PropType^^.Kind = tkChar) then
begin
reg.OpenKey(Key, True);
val := reg.ReadString(PropList[i].Name);
SetPropValue(Self,PropList[i].Name, val);
reg.CloseKey;
Continue;
end;
{------- Другие типы данных -------}
end;
finally
// высвобождаем память
FreeMem(PropList);
reg.Free;
end;
end;
Какие ограничения? Найти модуль можно здесь: config.zip (2 КБ) |
|---|
| © Зинкевич
Виктор, 2005 г. |