Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Объекты и TRegistry

Delphi , ОС и Железо , Реестр

Объекты и TRegistry

Кто-нибудь знает, как сохранить общие настройки шрифтов моей формы/пенели/списка и пр. пр. в регистрах; конечно, можно легко обойтись построчным сохранением, но, к примеру, в случае сохранения свойств шрифтов количество строк выйдет за пределы разумного - кто нибудь может подсказать мне решение покороче и полегче?

Delphi имеет маленький секрет, позволяющий рекурсивно сохранять в регистрах любые публичные свойства объектов. В качестве примера покажем как это работает для TFont.


uses TypInfo;

{ Определяем тип-набор для доступа к битам целого. }
const

  BitsPerByte = 8;
type

  TIntegerSet = set of 0..SizeOf(Integer) * BitsPerByte - 1;

  { Сохраняем набор свойств в виде подключа. Каждый элемент перечислимого типа -

  отдельная логическая величина. Истина означает что элемент включен в набор,
  Ложь - элемент в наборе отсутствует. Это позволит пользователю
  с помощью редактора ресурсов (REGEDIT) легко изменять конфигурацию. }

procedure SaveSetToRegistry(const Name: string; Value: Integer;

  TypeInfo: PTypeInfo; Reg: TRegistry);
var

  OldKey: string;
  I: Integer;
begin

  TypeInfo := GetTypeData(TypeInfo)^.CompType;
  OldKey := '\' + Reg.CurrentPath;
  if not Reg.OpenKey(Name, True) then
    raise ERegistryException.CreateFmt('Не могу создать ключ: %s',
      [Name]);

  { Организуем цикл для всех элементов перечислимого типа. }
  with GetTypeData(TypeInfo)^ do
    for I := MinValue to MaxValue do
      { Записываем логическую величину для каждого установленного элемента. }
      Reg.WriteBool(GetEnumName(TypeInfo, I), I in
        TIntegerSet(Value));

  { Возвращаем родительский ключ. }
  Reg.OpenKey(OldKey, False);
end;

{ Сохраняем объект в регистрах в отдельном подключе. }

procedure SaveObjToRegistry(const Name: string; Obj: TPersistent;

  Reg: TRegistry);
var

  OldKey: string;
begin

  OldKey := '\' + Reg.CurrentPath;
  { Открываем подключ для объекта. }
  if not Reg.OpenKey(Name, True) then
    raise ERegistryException.CreateFmt('Не могу создать ключ: %s',
      [Name]);

  { Сохраняем свойства объекта. }
  SaveToRegistry(Obj, Reg);

  { Возвращаем родительский ключ. }
  Reg.OpenKey(OldKey, False);
end;

{ Сохраняем в регистрах метод путем записи его имени. }

procedure SaveMethodToRegistry(const Name: string; const Method:
  TMethod;

  Reg: TRegistry);
var

  MethodName: string;
begin

  { Если указатель на метод содержит nil, сохраняем пустую строку. }
  if Method.Code = nil then
    MethodName := ''
  else
    { Находим имя метода. }
    MethodName := TObject(Method.Data).MethodName(Method.Code);
  Reg.WriteString(Name, MethodName);
end;

{ Сохраняем в регистре каждое свойство в виде значения текущего
ключа. }

procedure SavePropToRegistry(Obj: TPersistent; PropInfo: PPropInfo;
  Reg: TRegistry);
begin

  with PropInfo^ do
    case PropType^.Kind of
      tkInteger,
        tkChar,
        tkWChar:
        { Сохраняем порядковые свойства в виде целочисленного значения. }
        Reg.WriteInteger(Name, GetOrdProp(Obj, PropInfo));
      tkEnumeration:
        { Сохраняем имена перечислимых величин. }
        Reg.WriteString(Name, GetEnumName(PropType, GetOrdProp(Obj,
          PropInfo)));

      tkFloat:
        { Сохраняем реальные числа как Doubles. }
        Reg.WriteFloat(Name, GetFloatProp(Obj, PropInfo));
      tkString,
        tkLString:
        { Сохраняем строки как строки. }
        Reg.WriteString(Name, GetStrProp(Obj, PropInfo));
      tkVariant:
        { Сохраняем вариантные величины как строки. }
        Reg.WriteString(Name, GetVariantProp(Obj, PropInfo));
      tkSet:
        { Сохраняем набор как подключ. }
        SaveSetToRegistry(Name, GetOrdProp(Obj, PropInfo), PropType,
          Reg);

      tkClass:
        { Сохраняем класс как подключ, а его свойства
        в виде значений подключа. }
        SaveObjToRegistry(Name, TPersistent(GetOrdProp(Obj, PropInfo)),
          Reg);

      tkMethod:
        { Сохраняем в регистрах метод путем записи его имени. }
        SaveMethodToRegistry(Name, GetMethodProp(Obj, PropInfo), Reg);
    end;
end;

{ Записываем объект в регистр, сохраняя опубликованные свойства. }

procedure SaveToRegistry(Obj: TPersistent; Reg: TRegistry);
var

  PropList: PPropList;
  PropCount: Integer;
  I: Integer;
begin

  { Получаем список опубликованных свойств. }
  PropCount := GetTypeData(Obj.ClassInfo)^.PropCount;
  GetMem(PropList, PropCount * SizeOf(PPropInfo));
  try
    GetPropInfos(Obj.ClassInfo, PropList);
    { Сохраняем каждое свойство в виде значения текущего ключа. }
    for I := 0 to PropCount - 1 do
      SavePropToRegistry(Obj, PropList^[I], Reg);
  finally
    FreeMem(PropList, PropCount * SizeOf(PPropInfo));
  end;
end;

{ Сохраняем опубликованные свойства в виде значения данного ключа.

Корневой улей - HKEY_CURRENT_USER. }

procedure SaveToKey(Obj: TPersistent; const KeyPath: string);
var

  Reg: TRegistry;
begin

  Reg := TRegistry.Create;
  try
    if not Reg.OpenKey(KeyPath, True) then
      raise ERegistryException.CreateFmt('Не могу создать ключ: %s',
        [KeyPath]);

    SaveToRegistry(Obj, Reg);
  finally
    Reg.Free;
  end;
end;

Секрет Дельфи!

Код, который вы предоставили, - это обертка вокруг компонента TRegistry для сохранения и загрузки публичных свойств объекта в реестре Windows. Идея заключается в том, чтобы рекурсивно хранить свойства как набор булевых значений, которые можно легко редактировать с помощью REGEDIT.

Вот разбивка кода:

  1. SaveSetToRegistry: Процедура принимает целочисленное значение и сохраняет его в виде набора булевых значений в реестре. Она использует цикл для перебора всех элементов типа перечисления и записывает булевое значение для каждого элемента, который является частью множества.
  2. SaveObjToRegistry: Процедура сохраняет публичные свойства объекта в реестре, вызывая SaveToRegistry.
  3. SaveMethodToRegistry: Процедура сохраняет метод как строку в реестре, либо пустую, если указатель на метод равен nil, либо имя метода иначе.
  4. SavePropToRegistry: Процедура сохраняет свойство как значение соответствующего типа в реестре. Она обрабатывает различные типы свойств (целочисленное, символ, перечисление, вещественное, строка, вариант, множество, класс и метод).
  5. SaveToRegistry: Это основная процедура, которая рекурсивно перебирает публичные свойства объекта и сохраняет их в реестре с помощью вышеуказанных процедур.
  6. SaveToKey: Процедура вызывает SaveToRegistry с конкретным путем ключа.

Чтобы использовать этот код, вы создаете экземпляр TRegistry, открываете желаемый ключ в реестре (например, HKEY_CURRENT_USER), а затем вызываете SaveToRegistry или SaveToKey, чтобы сохранить свойства объекта. При загрузке свойств можно использовать соответствующие процедуры (например, LoadSetFromRegistry) для получения значений из реестра.

Обратите внимание, что это реализация является специфичной для Delphi и может не работать с другими языками программирования или фреймворками. Кроме того, будьте осведомлены о ограничениях и безопасности при работе с реестром Windows.

Объекты и TRegistry - это тайный способ Delphi для рекурсивного сохранения любых публичных свойств объектов в регистрах Windows.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Реестр ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 13:27:23/0.0060029029846191/1