На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Работа с ini файлами в Delphi , Компонент для работы с ini файлами KRIniConfig
    KRIniConfig - компонент для работы с ini файлами, представляет из себя коллекцию компонентов, где каждый компонент является параметром конфигурационного файла. Имя параметра является и именем компонента, что дает возможность обращаться к нему прямо из кода программы.

    Описание свойств и методов:
    https://kandiral.ru/delphi/kriniconfig.pas.html

    Пример использования с видеообзором:
    https://kandiral.ru/delphi/primer_ispolzova...riniconfig.html
      1. Как с помощью компонента сохранить другие свойства, кроме Value
      2. Где окно редактора компонента. Редактирование в Структуре весьма специфично.
      3. Как с помощью компонента сохранить свойства произвольного компонента, а не только с вашей библиотеки.
      4. "Монитор параметров" работает если мы вручную изменяем INI файл ?
      5. "Редактирование происходит по нажатию клавиши Enter" - это вы свои правила редактирование придумали ?
      6. "Нажали Enter" и куда делся фокус с компонента ? Чтобы продолжить ввод, нужно снова кликать мышкой в компонент ?
      7. "Вводим двоечку, а Минимальный предел 100". После возвращение в редактирование компонента введённая "Двоечка" исчезла. А если я вводил 10ти значное число и оно не прошло по условию, мне опять его вводить ?
      8.
      ExpandedWrap disabled
        //Чем принципиально отличается
        Param1.Value:=123; // Запись значения 123 в параметр Param1
        i:=Param1.Value; // Чтение значения из параметра Param1 в переменную i
        // от
        Ini.WriteString(Section,'Edit1',Edit.Text); // Запись значения 123 в параметр Param1
        Edit.Text := Ini.ReadString(Section,'Edit1',''); // Чтение значения из параметра
      Сообщение отредактировано: DimaBr -
        Цитата
        1. Как с помощью компонента сохранить другие свойства, кроме Value

        Какие другие свойства? Свойства Value принимает тип Variant и в зависимости от выставленного типа параметра можно устанавливать целочисленное, дробное, строковое или логическое значение

        Цитата
        2. Где окно редактора компонента. Редактирование в Структуре весьма специфично.

        Окно редактирования я не делал, но если будет такая необходимость сделаю

        Цитата
        3. Как с помощью компонента сохранить свойства произвольного компонента, а не только с вашей библиотеки.

        Мой компонент работает через TIniFile. Через свойство KRIniConfig.IniFile можно напрямую работать с ini файлом и сохранять все что угодно.

        Цитата
        4. "Монитор параметров" работает если мы вручную изменяем INI файл ?

        Нет. Мониторинг работает только если изменения производились через объект класса TKRIniCfgParam

        Цитата
        5. "Редактирование происходит по нажатию клавиши Enter" - это вы свои правила редактирование придумали ?

        Это не относится к данной теме, так как это другой компонент KRValueEdit. Да это было моё решение, чтобы установка значения и последующее событие о его изменении генерировались один раз по завершению ввода, а не при добавлении каждого символа.
        Одному из заказчиков не понравилось, что нужно нажимать Enter, как и Вам. Тогда я сделал ввод по потере фокуса, то есть фокус перешел на другой визуальный элемент, обрабатывается значение.

        Цитата
        6. "Нажали Enter" и куда делся фокус с компонента ? Чтобы продолжить ввод, нужно снова кликать мышкой в компонент ?

        Это опять же вопрос по компоненту KRValueEdit. Нажатие Enter предполагает окончание ввода значения

        Цитата
        7. "Вводим двоечку, а Минимальный предел 100". После возвращение в редактирование компонента введённая "Двоечка" исчезла. А если я вводил 10ти значное число и оно не прошло по условию, мне опять его вводить ?

        И снова KRValueEdit. Да, на данный момент так. Это можно исправить. Я и выкладываю свои разработки для выявления ошибок и модернизации.

        8. Я преследую цель уменьшить количество кода при разработке программ. В случае с TIniFile Вам понадобится указать расположение файла, создать объект, удалить объект, сохранять имена параметров и секций(в противном случае будут проблемы при ошибке в одну букву или регистр символа). В моём примере форма настроек с сохранением данных в конфигурационный файл имеет всего один метод с двумя строками кода, а используя TIniFile и стандартные визуальные компоненты сколько строк кода нужно для реализации той же задачи?
          1. Например сохранить Caption + Checked у CheckBox
          3. "Через свойство KRIniConfig.IniFile можно напрямую работать с ini файлом и сохранять все что угодно." - тогда в чём преимущество компонента, если кода для сохранения писать столько же ?
          4. Всё равно не понятно зачем нужен монитор, если сторонние изменения никак не мониторятся
          5. Окончание редактирования предполагает при потере фокуса. Это стандартное в любой программе. Зачем придумывать своё - непонятно.
          6. Потеря фокуса и окончание редактирование не связано между собой
          8. Повторяю, что количество строк кода не уменьшается, или я буду писать
          Param1.Value:=123; Ini.WriteInteger(Section,'Edit1',123); - одинаково
          Если это делается в одном единственном месте программы, то где автоматизация ?
          9. Как с помощью вашего компонента сохранить TMemo, TCheckListBox, TDateTimePicker, TTreeView, TImageList ?
          Сообщение отредактировано: DimaBr -
            1. Создать два параметра, один строковый другой булевы
            3. Я сделал доступ к TIniFile для того, чтобы при необходимости можно было с ним работать напрямую. Пока у меня возникает такая необходимость когда нужно работать с массивом параметров.
            4. Я в своих программах использую только свои конфигурационные параметры. И если один из параметров изменяется в одном месте, то при помощи мониторинг, другие объекты которые используют этот параметр будут знать об этом. Мониторинг это аналог события OnChange, только по событию можно вызвать один метод одного объекта, а в моем случае изменение могут видеть множество объектов
            5. Вы не правы. Окончание ввода подтверждается кнопкой Enter еще со времен доса. В Windows подтверждением вводя, в основном является кнопка "Ok". Я делал независимый компонент, который при изменении должен выдать значение.
            6. У меня возникла задача изменить способ ввода. Я ее решил таким путем и заказчика это устроило.
            8. Допустим есть задача при запуске приложения прочитать один параметр из конфигурационного файла
            ExpandedWrap disabled
              procedure TForm1.FormCreate(Sender: TObject);
              var
                cfg: TIniFile;
              begin
                cfg:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'config.ini');
                param1:=cfg.read('Section1','Param1',0);
                cfg.Free;
              end;

            ExpandedWrap disabled
              procedure TForm1.FormCreate(Sender: TObject);
              begin
                param1:=cfgParam1.Value;
              end;


            Добавлено
            9. TMemo, TCheckListBox, TTreeView это сохранение массивов. Как я писал выше, сохранение массивов я и сам делаю напрямую через TIniFile. Я думаю, сделаю это в ближайшее время. TDateTimePicker - это double значение, вполне можно сохранить через мой компонент. А что может понадобится сохранять из TImageList в ini файл?
            Сообщение отредактировано: kandiral -
              1. "Создать два параметра, один строковый другой булевы" - в вашем случае указывается имя компонента, который и является полем для сохранения в файл. Какое свойство компонента сохраняется в файл - НЕПОНЯТНО.

              5. Я пишу текст а Edit, нажимаю ENTER. Да я подтверждаю, что закончил ввод текста, но куда девается фокус ? Почему я не могу дальше редактировать текст. Раз уж на то пошло, то в DOSе нажание ENTER - это окончание редактирование и переход в следующее окно. А если подумать, то ENTER - переход в другое окно редактирования, а сам выход из текущего окна и есть окончание редактирования, поскольку перейти можно и мышкой.

              6. "У меня возникла задача изменить способ ввода. Я ее решил таким путем и заказчика это устроило." - а причём тут заказчик ? Вы же толкаете свой продукт в массы. А в массах, выход с поля редактирование подразумевает окончание ввода.

              8 "Допустим есть задача при запуске приложения прочитать один параметр из конфигурационного файла".
              Ну тут вы явно лукавите, в вашем случае строчек гораздо больше
              Скрытый текст
              ExpandedWrap disabled
                with TIniFile.Create(ExtractFilePath(Application.ExeName)+'config.ini') do begin
                  param1 := ReadInteger('Section1','Param1',0);
                  Free;
                end;

              и ваш код
              ExpandedWrap disabled
                TMyForm = class(TForm)
                  KRIniConfig: TKRIniConfig;
                  cfgParam1: TKRIniCfgParam;
                end;
                 
                begin
                  param1:=cfgParam1.Value;
                end;

              и плюс куча строк в dfm файле. Где выигрыш ?


              9. А что может понадобится сохранять из TImageList в ini файл?
              Картинки

              10. А как будет работать такой код ? Какой из CheckBox-ов сохраниться в файл ?
              ExpandedWrap disabled
                TMyForm = class(TForm)
                  CheckBoxParam: TKRIniCfgParam;
                  KRBKCheckBox1: TKRBKCheckBox;
                  KRBKCheckBox2: TKRBKCheckBox;
                end;
                begin
                  KRBKCheckBox1.CfgParam := CheckBoxParam;
                  KRBKCheckBox2.CfgParam := CheckBoxParam;


              11. Ваша "сохранялка" работает только с вашими компонентами. Подход неправильный. Нужно чтобы:
              a) сохранялка работала с любым компонентом
              б) можно было сохранять любое (хотя бы любое простое) свойство
              в) можно было добавить метод сохранения/чтения собственного типа
              г) сохранять на только в файл, но и в реестр
              д) удобный редактор, в котором можно выбрать компонент и какие свойства сохранять
                Вы, наверно, не правильно поняли цель моего компонента. Цель не сохранение значения свойства какого либо объекта, а цель сохранение конфигурационных данных программы.

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

                8. Я имею ввиду код набранный вручную. В моем случае его явно меньше. Цель упростить работу программисту, а тот код про который Вы говорите генерируется автоматически.

                9. Не вижу смысла хранить картинки в ini файле
                Сообщение отредактировано: kandiral -
                  "Вы, наверно, не правильно поняли цель моего компонента. Цель не сохранение значения свойства какого либо объекта, а цель сохранение конфигурационных данных программы. "
                  А размеры компонентов на форме - это не конфигурационные данные ?
                  Или ваш компонент умеет сохранять только Edit.Text и ничего более ?

                  Если уж так пошло, то какой смысл во внешних компонентах TKRIniCfgParam, если каждый их них соответствуют отдельному CheckBox-у. Уж проще в сам CheckBox добавить свойство Config: TKRIniConfig;
                  И сразу избавиться от огромного количества невидимых компонентов на форме (и в описании формы)

                  ExpandedWrap disabled
                    TKRBKCheckBox = class(TCheckBox)
                      property Config: TKRIniConfig read fConfig write SetConfig;
                    end;


                  или так

                  ExpandedWrap disabled
                    TSaveProp = class(TPersistent)
                      property Config: TKRIniConfig read fConfig write SetConfig;
                      property Encrypt .....;
                      property DefaultValue ....;
                      property TypProp .....;
                    end;
                    TKRBKCheckBox = class(TCheckBox)
                      property Config: TSaveProp read fConfig write SetConfig;
                    end;
                  Сообщение отредактировано: DimaBr -
                    Я не знаю как до Вас донести задачу моего компонента.
                    Вот пример сохранения состояния формы в ini файл.
                    ExpandedWrap disabled
                      unit Unit1;
                       
                      interface
                       
                      uses
                        Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                        Dialogs, KRComponentCollection, KRIniConfig;
                       
                      type
                        TForm1 = class(TForm)
                          KRIniConfig1: TKRIniConfig;
                          cfgMFLeft: TKRIniCfgParam;
                          cfgMFTop: TKRIniCfgParam;
                          cfgMFHeight: TKRIniCfgParam;
                          cfgMFWidth: TKRIniCfgParam;
                          cfgMFIsMaximized: TKRIniCfgParam;
                          procedure FormResize(Sender: TObject);
                          procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
                          procedure FormActivate(Sender: TObject);
                          procedure FormCreate(Sender: TObject);
                        private
                          isActivated: boolean;
                        end;
                       
                      var
                        Form1: TForm1;
                       
                      implementation
                       
                      {$R *.dfm}
                       
                      procedure TForm1.FormActivate(Sender: TObject);
                      begin
                        if isActivated then exit;
                        Left:=cfgMFLeft.Value;
                        Top:=cfgMFTop.Value;
                        Width:=cfgMFWidth.Value;
                        Height:=cfgMFHeight.Value;
                        if cfgMFIsMaximized.Value then WindowState:=wsMaximized;
                        isActivated:=true;
                      end;
                       
                      procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
                      begin
                        if WindowState<>wsMaximized then begin
                          cfgMFLeft.Value:=Left;
                          cfgMFTop.Value:=Top;
                          cfgMFIsMaximized.Value:=false;
                        end else cfgMFIsMaximized.Value:=true;
                      end;
                       
                      procedure TForm1.FormCreate(Sender: TObject);
                      begin
                        isActivated:=false;
                      end;
                       
                      procedure TForm1.FormResize(Sender: TObject);
                      begin
                        if not isActivated then exit;
                        if WindowState<>wsMaximized then begin
                          cfgMFLeft.Value:=Left;
                          cfgMFTop.Value:=Top;
                          cfgMFWidth.Value:=Width;
                          cfgMFHeight.Value:=Height;
                        end;
                      end;
                       
                      end.

                    ExpandedWrap disabled
                      object Form1: TForm1
                        Left = 0
                        Top = 0
                        Caption = 'Form1'
                        ClientHeight = 282
                        ClientWidth = 418
                        Color = clBtnFace
                        Font.Charset = DEFAULT_CHARSET
                        Font.Color = clWindowText
                        Font.Height = -11
                        Font.Name = 'Tahoma'
                        Font.Style = []
                        OldCreateOrder = False
                        OnActivate = FormActivate
                        OnCloseQuery = FormCloseQuery
                        OnCreate = FormCreate
                        OnResize = FormResize
                        PixelsPerInch = 96
                        TextHeight = 13
                        object KRIniConfig1: TKRIniConfig
                          FileName = 'config.ini'
                          Left = 144
                          Top = 64
                          object cfgMFLeft: TKRIniCfgParam
                            Section = 'MainForm'
                            ValueType = icvtInteger
                            DefaultValue = '0'
                            Encrypt = False
                          end
                          object cfgMFTop: TKRIniCfgParam
                            Section = 'MainForm'
                            ValueType = icvtInteger
                            DefaultValue = '0'
                            Encrypt = False
                          end
                          object cfgMFHeight: TKRIniCfgParam
                            Section = 'MainForm'
                            ValueType = icvtInteger
                            DefaultValue = '320'
                            Encrypt = False
                          end
                          object cfgMFWidth: TKRIniCfgParam
                            Section = 'MainForm'
                            ValueType = icvtInteger
                            DefaultValue = '400'
                            Encrypt = False
                          end
                          object cfgMFIsMaximized: TKRIniCfgParam
                            Section = 'MainForm'
                            ValueType = icvtBool
                            DefaultValue = 'False'
                            Encrypt = False
                          end
                        end
                      end


                    Содержимое ini файла
                    ExpandedWrap disabled
                      [MainForm]
                      cfgMFHeight=188
                      cfgMFWidth=234
                      cfgMFLeft=720
                      cfgMFTop=154
                      cfgMFIsMaximized=0

                    Прикреплённый файлПрикреплённый файлFormPosToFile.zip (84,65 Кбайт, скачиваний: 1162)
                      Мой код не длиннее вашего и без использования компонент. Где автоматизация ?
                      Скрытый текст
                      ExpandedWrap disabled
                        procedure TForm1.FormActivate(Sender: TObject);
                        begin
                          if isActivated then exit;
                          with TIniFile.Create(ExtractFilePath(Application.ExeName)+'config.ini') do begin
                            Left := ReadInteger('Section','Left',0);
                            Top := ReadInteger('Section','Top',0);
                            Width := ReadInteger('Section','Width',0);;
                            Height := ReadInteger('Section','Height',0);
                            if ReadBoolean('Section','Max',false) then WindowState:=wsMaximized;
                            Free;
                          end;
                          isActivated:=true;
                        end;
                         
                        procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
                        begin
                          FormResize(Sender);
                        end;
                         
                        procedure TForm1.FormCreate(Sender: TObject);
                        begin
                          isActivated:=false;
                        end;
                         
                        procedure TForm1.FormResize(Sender: TObject);
                        begin
                          if not isActivated then exit;
                          with TIniFile.Create(ExtractFilePath(Application.ExeName)+'config.ini') do begin
                           if WindowState<>wsMaximized then begin
                             WriteInteger('Section','Left',Left);
                             WriteInteger('Section','Top',Left);
                             WriteInteger('Section','Width',Width);
                             WriteInteger('Section','Height',Heigth);
                           end;
                           WriteBoolean('Section','Max',WindowState<>wsMaximized);
                          end;
                        end;


                      Вы продолжаете игнорировать вопросы. Особенно № 10. Можно ли ОДИН параметр прицепить к двум компонентам, и что при этом будет сохраняться ?
                      Если количество параметров (TKRIniCfgParam) всегда равно количеству компонентов, то какой в них вообще смысл ?
                        Цитата kandiral @
                        ExpandedWrap disabled
                            TForm1 = class(TForm)
                              KRIniConfig1: TKRIniConfig;
                              cfgMFLeft: TKRIniCfgParam;
                              cfgMFTop: TKRIniCfgParam;
                              cfgMFHeight: TKRIniCfgParam;
                              cfgMFWidth: TKRIniCfgParam;
                              cfgMFIsMaximized: TKRIniCfgParam;

                        ОМГ.
                        За желание обнародовать свою работу - хвала, но в таком виде неюзабельно имхо. Ну и ini файлы это прошлый век, как насчет json, xml?
                          Цитата
                          За желание обнародовать свою работу - хвала, но в таком виде неюзабельно имхо.

                          В данном примере это конечно сильно круто использовать столько объектов для такой простой задачи. Но это был всего лишь пример для демонстрации.
                          Но представьте, мы имеем большой проект, множество форм и нам нужен параметр из файла, который используется в нескольких формах(объектах). Я решаю такую задачу, создав TKRIniConfig с параметрами на главной форме и все другие формы(объекты) используют эти параметры. То есть больше ни где не нужно подключатся к конфигурационному файлу, не нужно где-то хранить имена параметров и секций, мы просто обращаемся к объекту из главной формы MainForm.Param1
                          Мне это сильно упростило жизнь и я решил поделится эти.


                          Цитата
                          Ну и ini файлы это прошлый век, как насчет json, xml?

                          Не скажите. Сделайте поиск с маской *.ini в папке Windows и посчитайте сколько там таких файлов. Формат хранения не особо важен, при желании можно доработать этот компонент и сохранять данные в json или xml. Суть в способе использования конфигурационных параметров из файла как отдельный объект. Плюс я уже пошел дальше и эти объект использую в других компонентах как показано в примере на сайте
                            Можно ли ОДИН параметр прицепить к двум компонентам, и что при этом будет сохраняться ?
                              Цитата
                              Можно ли ОДИН параметр прицепить к двум компонентам, и что при этом будет сохраняться ?

                              Если один и тот же параметр прикрепить к разным компонентам, то при изменении значения в одном компоненте оно поменяется и во втором.
                              То есть например возьмем два выпадающих списка KRComboBox с одним и тем же конфигурационном параметром и в первом списке мы изменим выбранный элемент, то во втором списке сразу изменится значение на соответствующее. При этом сохранятся будет номер выбранного элемента. При этом не имеет значение сколько компонентов с одинаковым параметром два или более, все синхронно будут изменятся.
                              Сообщение отредактировано: kandiral -
                                То есть изменение в компоненте сразу же сохраняется в Ini файле ? А как же процедуры Ok / Cancel о которых говорится в видео ?
                                Сообщение отредактировано: DimaBr -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0496 ]   [ 18 queries used ]   [ Generated: 28.03.24, 23:28 GMT ]