|
|
|||||||
---|---|---|---|---|---|---|---|---|
Сохранение настроек в реестр |
|
Лень движет прогресс! Это я к тому, что чем больше я ленюсь набирать тексты программ, тем больше я придумываю всяких инструментов, чтобы облегчить себе труд. На этот раз я изобрел (быть может велосипед, но САМ!) компонент, который свои свойства, объявленные в разделе 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 г. |