Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Хранение описания всех контролов формы, обработчиков событий, настроек в БД

88K
10 июля 2014 года
the_man
2 / / 10.07.2014
Добрый день, Уважаемые коллеги!
Направьте в какую сторону копать.
Есть идея хранить описания всех контролов, обработчиков событий, настроек программы в Базе Данных и при запуске приложения строить форму динамически.
Это удобно, когда нужно сделать апдейт, не обновляя экзешник.
Кто-нибудь сталкивался?
В принципе как хранить описания контролов более менее кажется интуитивно понятным, но вот как хранить код??? А самое главное как его потом исполнять без компиляции???
Заранее благодарен.
326
11 июля 2014 года
sadovoya
757 / / 19.11.2005
1)Хранить настройки программы отдельно от нее -- нормальная практика. Смело используйте.
2)Изменяемый код лучше компилировать в отдельные бинарники (часто dll-библиотеки для этого используют, но можно и объектники). Схема примерно такая: например, код обработчика события вызывает внешнюю функцию. Внешняя функция хранится откомпилированной в dll-ке. Если нужно поменять ее реализацию (не трогайте ее название и параметры), то просто меняете код исходника dll для этой ф-ции и dll заново компилируете. Т.е. не всю программу придется перекомпилировать, а только dll. Пользователю в качестве обновления потребуется лишь dll-ка.
3)Существует еще такая вещь как сериализация. Тут много нюансов. Можете почитать в сети для общего развития.
8
11 июля 2014 года
mfender
3.5K / / 15.06.2005
Зачем хранить обработчики? Или имеется ввиду Live bind ?
Геометрию контролов хранить чертовски просто. Например в INI файле.
я себе множество вариантов сохранения всего делал когда-то. Где-то валяется ещё для D7 сохранение всех published в INI через RTTI.

Код:
procedure TIniAppGeometry.WriteBounds(ASection, AIdent: string;
  var AControl: TControl);
var
  R: ^TRect;
  S: TStream;
begin
  try
    if Assigned(AControl) then
    begin
      New(R);
      R^ := AControl.BoundsRect;
      S := TMemoryStream.Create;
      try
        S.WriteBuffer(R^, SizeOf(R^));
        S.Position := 0;
        WriteBinaryStream(ASection, AIdent, S);
      finally
        FreeAndNil(S);
      end;
    end;
  except
  end;
end;
Ну и в цикле эту беду вызвать для всех контролов формы:

Код:
procedure TIniAppGeometry.MagicWriteBounds(var AControl: TControl;
  ASection, APrefix: string);
var
  I: Integer;
  C: TControl;
begin
  WriteBounds(ASection, APrefix + AControl.Name, AControl);
  for I := 0 to Pred(AControl.ComponentCount) do
  begin
    if AControl.Components[I].Name <> '' then
    begin
      C := TControl(AControl.Components[I]);
      WriteBounds(ASection, APrefix + C.Name, C);
    end;
  end;
end;
Потом так же читать обратно:

Код:
procedure TIniAppGeometry.ReadBounds(ASection, AIdent: string;
  var AControl: TControl);
var
  R: ^TRect;
  S: TStream;
begin
  try
    S := TMemoryStream.Create;
    New(R);
    try
      ReadBinaryStream(ASection, AIdent, S);
      S.Position := 0;
      S.ReadBuffer(R^, SizeOf(R^));
      AControl.BoundsRect := R^;
    finally
      Dispose(R);
      S.Free;
    end;
  except

  end;
end;
88K
12 июля 2014 года
the_man
2 / / 10.07.2014
Цитата: sadovoya
1)Хранить настройки программы отдельно от нее -- нормальная практика. Смело используйте.
2)Изменяемый код лучше компилировать в отдельные бинарники (часто dll-библиотеки для этого используют, но можно и объектники). Схема примерно такая: например, код обработчика события вызывает внешнюю функцию. Внешняя функция хранится откомпилированной в dll-ке. Если нужно поменять ее реализацию (не трогайте ее название и параметры), то просто меняете код исходника dll для этой ф-ции и dll заново компилируете. Т.е. не всю программу придется перекомпилировать, а только dll. Пользователю в качестве обновления потребуется лишь dll-ка.
3)Существует еще такая вещь как сериализация. Тут много нюансов. Можете почитать в сети для общего развития.


А если понадобится вдруг добавить новую функциональность?
Хотелось бы обходится без перекомпила экзешника

326
12 июля 2014 года
sadovoya
757 / / 19.11.2005
Для добавления функциональности часто используют технологию плагинного расширения (можно через подключение dll). Разумеется не везде это уместно. В любом случае все через бинарники. Если только вы не напишите транслятор или компиляцию на-лету :)
Лучше задумайтесь о принципах организации своего кода для удобного повторного применение в будущих программах и о модифицируемости/расширяемости кода. Имею ввиду иерархии классов и прочий ООП, а также грамотное размещение кода по единицам трансляции. А компилировать не такой уж гемор, особенно если вы построите программу модульно, а не одним экзешником.

По поводу хранения настрек/свойств. Был в Delphi 6 удобный класс TIniFile. Он предоставляет средства для записи и чтения в ini-файл (по-сути обычный текстовый файл). Пример работы:

Код:
uses .... inifiles;

....

procedure TMainForm.ReadParams; // Чтение данных пользователя из ini-файла
Var
  IniFile:TIniFile;
begin
  IniFile:=TIniFile.Create(Path+'UserData.ini');

  Top:=IniFile.ReadInteger('Главная форма','Координата верха',100);
  Left:=IniFile.ReadInteger('Главная форма','Координата левой стороны',130);
  Combobox1.Text:=IniFile.ReadString('Данные','Длина волны','1064');
  Combobox6.Text:=IniFile.ReadString('Данные','Длина резонатора','100');
  Combobox4.Text:=IniFile.ReadString('Данные','Фокус линзы','-1000');
  Combobox5.Text:=IniFile.ReadString('Данные','Координата линзы','50');
  Combobox2.Text:=IniFile.ReadString('Данные','R глух. зеркала','-1500');
  Combobox3.Text:=IniFile.ReadString('Данные','R вых. зеркала','150');
  ComboBox7.Text:=IniFile.ReadString('Масштаб','Диаметр линзы','1');
  LabeledEdit2.Text:=IniFile.ReadString('Диапазон линз','P1','7');
  LabeledEdit3.Text:=IniFile.ReadString('Диапазон линз','P2','10');
  CheckBox1.Checked:=IniFile.ReadBool('Флажки','TEM00',True);
  CheckBox2.Checked:=IniFile.ReadBool('Флажки','TEM01',False);
  CheckBox3.Checked:=IniFile.ReadBool('Флажки','TEM11',True);
  CheckBox4.Checked:=IniFile.ReadBool('Флажки','TEM02',False);
  CheckBox5.Checked:=IniFile.ReadBool('Флажки','TEM12',True);
  CheckBox6.Checked:=IniFile.ReadBool('Флажки','TEM22',False);

  IniFile.Free;

end;

procedure TMainForm.WriteParams; // Запись в ini-файл пользовательских данных
Var
  IniFile:TIniFile;
begin
  IniFile:=TIniFile.Create(Path+'UserData.ini'); // создаем переменную

  IniFile.WriteInteger('Главная форма','Координата верха',Top);
  IniFile.WriteInteger('Главная форма','Координата левой стороны',Left);
  IniFile.WriteString('Данные','Длина волны',ComboBox1.Text);
  IniFile.WriteString('Данные','Длина резонатора',ComboBox6.Text);
  IniFile.WriteString('Данные','Фокус линзы',ComboBox4.Text);
  IniFile.WriteString('Данные','Координата линзы',ComboBox5.Text);
  IniFile.WriteString('Данные','R глух. зеркала',ComboBox2.Text);
  IniFile.WriteString('Данные','R вых. зеркала',ComboBox3.Text);
  IniFile.WriteString('Масштаб','Диаметр линзы',ComboBox7.Text);
  IniFile.WriteString('Диапазон линз','P1',LabeledEdit2.Text);
  IniFile.WriteString('Диапазон линз','P2',LabeledEdit3.Text);
  IniFile.WriteBool('Флажки','TEM00',CheckBox1.Checked);
  IniFile.WriteBool('Флажки','TEM01',CheckBox2.Checked);
  IniFile.WriteBool('Флажки','TEM11',CheckBox3.Checked);
  IniFile.WriteBool('Флажки','TEM02',CheckBox4.Checked);
  IniFile.WriteBool('Флажки','TEM12',CheckBox5.Checked);
  IniFile.WriteBool('Флажки','TEM22',CheckBox6.Checked);

  IniFile.Free;

end;
Я код подсократил, нужна еще обработка исключений.

В новых версиях Дельфи возможно появились более продвинутые классы, например, для работы через XML.

Еще стандартный путь - хранение в реестре и чтение из него. Для "portable"- программ не подходит (те, которые работают с флешки и все свое держат в собственной папке). Кроме того потребуется позаботиться об уборке мусора из реестра при удалении программы с компа.
8
13 июля 2014 года
mfender
3.5K / / 15.06.2005
Реестром вообще лучше не пользоваться, особенно если хочется мультиплатформенную программу сделать.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог