Заметки · 10.11.2023

Пишем и читаем в INI

Чтобы сохранить или считать настройки элементов управления формы в IDE Lazarus есть прекрасный невизуальный компонент — IniPropStorage (вкладка Misc). Он позволяет работать с ini файлом, не нагромождая код и настраивать взаимодействие с конфигурацией прямо из IDE.

Отличная штука, которая ускоряет разработку, но усложняет чтение файлов конфигурации в дальнейшем. Особенно если к файлу конфигурации будет обращаться тот, кто исходного кода проекта в глаза не видел. Приведу пример.

В проекте присутствует форма с кнопкой. Наша задача — изменить свойство Caption кнопки Button1 на любой текст, который можно задать во внешнем файле конфигурации.

Размещаем на форме IniPropStorage. Для простоты называем его ini.

И настраиваем вот так:

Здесь я задал имя будущему файлу конфигурации — settings.ini. Теперь добавим в свойствах формы значение параметру SessionProperties.

Активировав упомянутое свойство формы попадаем в окно настроек.

Выделяем слева компонент Button1, а справа выбираем свойство Caption. Жмём на кнопку «Добавить«. В выбранных свойствах появилось то, что нам нужно. Окействуем.

Свойство формы SessionProperties выглядит вот так:

Собираем приложение и запускаем. После первого запуска будет сформирован файл settings.ini с вот такой структурой:

Структура файла конфигурации была сформирована с учётом формы приложения, где парой ключ-значение мы видим Caption нашей кнопки Button1. Даже если учесть, что кнопке Button1, да и самой форме Form1 в целом, мы дадим хоть сколько вменяемые имена — читабельность файла конфигурации оставит желать лучшего. Особенно много веселья будет, когда начнётся подготовка документации программного продукта. Впрочем оставим рассуждения и продолжим.

Заменим в файле settings.ini значение Button1 параметра Button1_Caption на слово Текст и запустим приложение.

Приложение считало данные из файла конфигурации и присвоило кнопке заданную надпись.

Теперь сделаем всё это своими руками с созданием собственного уникального и легкочитаемого файла конфигурации прямо из кода.

Обязательно подключаем модуль IniFiles для работы с файлами формата ini, а для функции чтения настроек ReadSettings подключим ещё и SysUtils (как правило, этот модуль уже подключен по умолчанию).

С помощью функции ReadSettings можно прочитать настройки из указанного файла конфигурации. Функция принимает в качестве входных данных имя ini-файла (или путь к нему), секцию и параметр, а возвращает значение указанного параметра с типом данных string.

uses ..., SysUtils, IniFiles, ...;

function ReadSettings(filename, section, param: string):string;
var
  inifile: TINIFile;
  data: string;
begin
  if FileExists(filename) then
     begin
       inifile:=TINIFile.Create(filename);
       data:=inifile.ReadString(section, param, data);
       inifile.Free;
       result:=data;
     end
  else result:=filename + ' not found';
end;

Если конфигурация должна подгружаться при старте приложения лучше указать всё, что нужно в процедуре создания формы (FormCreate):

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.Caption:=ReadSettings('settings.ini', 'Button1', 'Caption');
end; 

Допустим, наш файл конфигурации settings.ini выглядит вот так:

[Button1]
Caption=Снова текст

В итоге при запуске приложения форма будет выглядеть так:

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

Для записи в файл конфигурации можно использовать функцию WriteSettings:

uses ..., IniFiles, ...;

function WriteSettings(filename, section, param, value: string):boolean;
var
  inifile: TINIFile;
begin
  try
    inifile:=TINIFile.Create(filename);
    inifile.WriteString(section, param, value);
    inifile.Free;
    result:=True;
  except
    result:=False;
  end;
end; 

WriteSettings принимает имя ini-файла, секцию, параметр и значение. Если файл конфигурации уже существует — функция допишет данные и не тронет предыдущие параметры.

Применить функцию в коде можно вот так:

WriteSettings('settings.ini','Test','Enable','True');

Функция возвращает логические значения и можно легко отследить получилось записать данные в файл или нет.

Если появится время — запихну указанные функции в отдельный модуль и размещу в соответствующем разделе.