Статьи по программированию
примеры программного кода
Delphi, Kylix, C, C++, SQL, Visual Basic, Bash, Assembler, 1С
Qt, KOL, MFC, Rx Library, Windows, Linux, Mac OS
Универсальный алгоритм сохранения настроек
Опубликовано codeLocker в 18.07.2008 в 15:32.
Во время своего опыта в роли программиста частенько приходилось создавать программы, где имелось большое количество различных параметров, опций и настроек... Думаю я не один, кто сталкивался с этим. Так вот сохранение всех этих настроек и последующее их считывание, например с реестра или .ini файла всегда было ужасом. Вот недавно опять натолкнулся на эту проблему... Но в этот раз было так скучно и лениво было писать что-то вроде:
R := TRegIniFile.Create;
R.RootKey := HKEY_CURRENT_USER;
R.OpenKey('Software\XXX', True);
R.WriteInteger(Section, 'Left', Left);
R.WriteInteger(Section, 'Top', Top);
R.WriteBool(Section, 'StayOnTop', chStay.Checked);
R.WriteInteger(Section, 'Refresh', Track.Position);
R.WriteInteger(Section, 'Alpha', TrackBarAlpha.Position);
R.WriteBool(Section, 'Snap', chScreenSnap.Checked);
R.WriteBool(Section, 'Baloon', chBaloonHint.Checked);
R.WriteBool(Section, 'vis', boolean(tag));
R.WriteString(Section, 'File', FileName.Hint);
R.WriteInteger(Section, 'Old', Old);
R.WriteInteger(Section, 'First', First);
R.CloseKey;
R.Free
R.RootKey := HKEY_CURRENT_USER;
R.OpenKey('Software\XXX', True);
R.WriteInteger(Section, 'Left', Left);
R.WriteInteger(Section, 'Top', Top);
R.WriteBool(Section, 'StayOnTop', chStay.Checked);
R.WriteInteger(Section, 'Refresh', Track.Position);
R.WriteInteger(Section, 'Alpha', TrackBarAlpha.Position);
R.WriteBool(Section, 'Snap', chScreenSnap.Checked);
R.WriteBool(Section, 'Baloon', chBaloonHint.Checked);
R.WriteBool(Section, 'vis', boolean(tag));
R.WriteString(Section, 'File', FileName.Hint);
R.WriteInteger(Section, 'Old', Old);
R.WriteInteger(Section, 'First', First);
R.CloseKey;
R.Free
... так что я решил этот процесс автоматизировать хоть немного. В общем придумал я следующее. Взять форму настроек и пробежаться в цикле по всем контролам, попутно записывая их основные свойства в буфер, который потом и записать одним махом, например в реестр. Для считывания настроек проделать тот же процесс, только в обратном порядке.
Procedure TfrmSettings.SaveSettings;
var settings: TMemoryStream;
R: TRegistry;
j: byte;
S: PChar;
b: boolean;
l: word;
begin
settings := TMemoryStream.Create;
for j := 0 to ControlCount - 1 do
if Controls[j] is TCheckBox then begin
b := TCheckBox(Controls[j]).Checked;
settings.WriteBuffer(b, 1);
end else
if Controls[j] is TEdit then begin
S := PChar(TEdit(Controls[j]).Text);
l := length(S);
settings.WriteBuffer(l, 2);
if l > 0 then settings.WriteBuffer(S^, l);
end;
R := TRegistry.Create;
R.RootKey := HKEY_CURRENT_USER;
R.OpenKey(‘Software\XXX’, true);
settings.Seek(0, soFromBeginning);
R.WriteBinaryData(‘settings’, settings.Memory^, settings.Size);
R.Free;
settings.free;
end;
var settings: TMemoryStream;
R: TRegistry;
j: byte;
S: PChar;
b: boolean;
l: word;
begin
settings := TMemoryStream.Create;
for j := 0 to ControlCount - 1 do
if Controls[j] is TCheckBox then begin
b := TCheckBox(Controls[j]).Checked;
settings.WriteBuffer(b, 1);
end else
if Controls[j] is TEdit then begin
S := PChar(TEdit(Controls[j]).Text);
l := length(S);
settings.WriteBuffer(l, 2);
if l > 0 then settings.WriteBuffer(S^, l);
end;
R := TRegistry.Create;
R.RootKey := HKEY_CURRENT_USER;
R.OpenKey(‘Software\XXX’, true);
settings.Seek(0, soFromBeginning);
R.WriteBinaryData(‘settings’, settings.Memory^, settings.Size);
R.Free;
settings.free;
end;
первое, что делает процедура, это создает поток данных в памяти, он как раз и будет тем буфером, в котором и будут храниться все настройки. Далее процедура начинает перебор всех компонентов на форме. Если очередной компонент является TCheckBox или TEdit, то в буфер записываются их основные свойства, т.е. Checked и Text соответственно. Далее мы записываем буфер как двоичные данные в реестр.
Процедура загрузки будет выглядеть следующим образом:
procedure TfrmSettings.LoadSettings;
var settings: TMemoryStream;
R: TRegistry;
buf: PChar;
size: integer;
j: byte;
b: boolean;
l: word;
begin
R := TRegistry.Create;
R.RootKey := HKEY_CURRENT_USER;
R.OpenKey(‘Software\XXX’, true);
if R.ValueExists(‘settings’) then begin
size := R.GetDataSize(‘settings’);
buf := GetMemory(size);
R.ReadBinaryData(‘settings’, buf^, size);
settings := TMemoryStream.Create;
settings.Write(buf^, size);
FreeMemory(buf);
settings.Seek(0, soFromBeginning);
for j := 0 to ControlCount - 1 do
if Controls[j] is TCheckBox then begin
settings.ReadBuffer(b, 1);
TCheckBox(Controls[j]).Checked := b
end else
if Controls[j] is TEdit then begin
settings.ReadBuffer(l, 2);
if l > 0 then begin
buf := GetMemory(l);
settings.ReadBuffer(buf^, l);
TEdit(Controls[j]).Text := copy(buf, 1, l);
FreeMemory(buf)
end;
end;
settings.Free;
end;
R.Free;
end;
var settings: TMemoryStream;
R: TRegistry;
buf: PChar;
size: integer;
j: byte;
b: boolean;
l: word;
begin
R := TRegistry.Create;
R.RootKey := HKEY_CURRENT_USER;
R.OpenKey(‘Software\XXX’, true);
if R.ValueExists(‘settings’) then begin
size := R.GetDataSize(‘settings’);
buf := GetMemory(size);
R.ReadBinaryData(‘settings’, buf^, size);
settings := TMemoryStream.Create;
settings.Write(buf^, size);
FreeMemory(buf);
settings.Seek(0, soFromBeginning);
for j := 0 to ControlCount - 1 do
if Controls[j] is TCheckBox then begin
settings.ReadBuffer(b, 1);
TCheckBox(Controls[j]).Checked := b
end else
if Controls[j] is TEdit then begin
settings.ReadBuffer(l, 2);
if l > 0 then begin
buf := GetMemory(l);
settings.ReadBuffer(buf^, l);
TEdit(Controls[j]).Text := copy(buf, 1, l);
FreeMemory(buf)
end;
end;
settings.Free;
end;
R.Free;
end;
Т.е. сначала получаем размер записанных настроек, выделяем под них память, считываем, переносим для удобства в TMemoryStream и считываем. Порядок не нарушается, т.к. пробег по контролам всегда идет по строго определенной последовательности указанной TabOrder. Все! Теперь можно добавлять новые настройки, удалять старые и не изменять код. В данном случае код упрошен, необходимо предусмотреть также обход контролов на панелях (TPanel), группах (TGroupBox) и т.п.
Материал похожий на Универсальный алгоритм сохранения настроек
- Определение восхода и захода солнца
- Управление игрой FreeCell
- Удаление каталога с подкаталогами
- Удаление колонки в StringGrid
Метки
автоматизация сортировки файл сортировка в обратном порядке контрольная работа по теме текст
Навигация
Сейчас на сайте
Сейчас на сайте 0 пользователей и 2 гостя.
Статистика
Всего материалов: 1387