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

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

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

    Прикреплённый файлПрикреплённый файлProga_component.rar (16,57 Кбайт, скачиваний: 168)
      1) зачем компоненту OD1: TOpenDialog; ведь у него есть свойство FileName
      2) зачем ему свойство Active если оно по своей сути никакой пользы не несет. я бы еще понял если бы по весить событие для открытия или закрытия файл по изменению свойства.
      3) связь между Access1, ID и Vivod вообще бредовая. намного эффективнее написать:
      ExpandedWrap disabled
        type
          TTest = class(TComponent)
          protected
           function element(ID: Integer): String; // имя функции оставил твое. хотя я бы его назвал
                               //по частичному имени свойства GetViyod что бы не путаться если свойств много
          public
            property Viyod[ID: Integer]: String read element;
          end;
         
        function TTest.element(ID: Integer): String;
        begin
          // а тут уже то что у тебя было в функции element
        end;

      4) я бы отказался от AssignFile. это пережитки паскаля. в данном случае намного проще было бы заюзать TStringList

      Добавлено
      пс. хотя ты изобрел велосипед. подобная логика уже в TStringList

      а что ты этим хотел сделать. может уже давно в делфи все готовое есть?
        Задание по курсовой такое, хочу для себя во первых норм разобраться, а во-вторых нужно же будет ещё объяснить что у меня к чему). За помощь огромное спс всеми советами воспользовался кроме 4-го, ток пока не пашет я ещё немного с приравниваниями напортачил
          Цитата Rydj @
          Задание по курсовой такое
          аха. тогда нужно оставить AssignFile. препод это оценит. (не знаю почему но большинство преподавателей считают что в делфи нужно писать на паскале, минуя богатые возможности Delphi. но возможно это часть идеи обучения)

          ну и небольшая доработка Active (что бы как то на компонент похоже было. ато одна полезная процедура как то не интересно)
          ExpandedWrap disabled
              TTest = class(...)
               FActive: Boolean;
              protected
               procedure SetActive(Value: Boolean);
              published
               property Active: Boolean read FActive write SetActive;
              public
               procedure Open;
               procedure Close;
              end;
             
            procedure TTest.Open;
            begin
              if Active then Exit;
              //дальше код который в процедуре OpenRead
              //и если загрузка прошла удачно то меняем флаг FActive на истину
            end;
             
            procedure TTest.Close;
            begin
              Setlength(fData, 0);
              FActive := false;
            end;
             
            procedure TTest.SetActive(Value: Boolean);
            begin
              if FActive = Value then Exit;
              if Value then Open
               else Close;
            end;
          Для открытия можно будет вызвать как процедуру Open так и присвоение истины свойству Active
            FActive: Boolean; вешать надо наверно в private
            и ещё вопросик я вот не пойму а от куда property Vivod[ID: Integer]: String read element; получает ID уж точно не с object inspectora
              Цитата Rydj @
              FActive: Boolean; вешать надо наверно в private
              да. я просто забыл написать (пишу код прямо сюда посему могут быть мелкие недочеты)

              Viyod не является published посему оно и не будет видно в инспекторе. да оно и не надо там.
              доступ к нужному элементу массива будет осуществятся:
              ExpandedWrap disabled
                var
                  test: TTest;
                begin
                  // тут создание test. хотя если компонент будет брошен визуально на форму то создавать не надо
                  ShowMessage(test.Viyod[1]); и тут в месседж будет выведено значения с первым индексом.

              а если написать свойство так
              ExpandedWrap disabled
                  public
                    property Viyod[ID: Integer]: String read element; default;
              То доступ к элементам массива можно будет получить без явного указания Viyod.
              ExpandedWrap disabled
                  ShowMessage(test[1]); // что немного сокращает код
                С Active компонент теперь действительно похож на компонент спасибо, вот ток доступ к элементам я получить не могу
                ExpandedWrap disabled
                  Button1.Caption:=Ttest.Vivod[1];

                получаем Undeclared identifier:'Vivod'

                Код компонента:
                ExpandedWrap disabled
                  type
                    Tknyz = class(TComponent)
                   
                    private
                      { Private declarations }
                     VFileName: string;
                      FActive: Boolean;
                     fData: array of string; //ìàññèâ
                      k:integer;       // VID-îáðàùåíèå ê âûáðàííîìó ýëåìåíòó ìàññèâà, k-ìàêñèìàëüíûé ýëåìåíò ìàññèâà
                   
                   
                    protected
                      { Protected declarations }
                     function GetVivod(ID: Integer): String;
                     procedure SetActive(Value: Boolean);
                   
                    public
                      { Public declarations }
                     constructor Create(AOwner: TComponent); override;
                     destructor Destroy; override;
                     procedure Open;
                     procedure Close;
                     property Vivod[ID: Integer]: String read GetVivod;
                   
                    published
                      { Published declarations }
                      property Active: Boolean read FActive write SetActive;
                      property FileName: string read VFileName write VFileName;
                    end;
                   
                  procedure Register;
                   
                  implementation
                  function Tknyz.GetVivod(ID: Integer): String;
                  begin
                    if ((ID<0) or (ID>=k) ) then
                        begin
                        messageDlg('Âîò òàê äåëàòü íåëüçÿ!', mtError, [mbOK],0);
                        end
                      else
                        begin
                        Result:=fData[ID];
                        end;
                  end;
                  По идеи должен. сообщение
                  Цитата Rydj @
                  получаем Undeclared identifier:'Vivod'
                  говорит о том что компилятор не видит Vivod. Дай полный код компонента + его использования
                    ExpandedWrap disabled
                      unit knyz;
                       
                      interface
                       
                      uses
                        Windows, Messages, SysUtils, Variants, Classes,
                        Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;
                       
                      type
                        Tknyz = class(TComponent)
                       
                        private
                          { Private declarations }
                         VFileName: string;
                          FActive: Boolean;
                         fData: array of string; //массив
                          k:integer;       // VID-обращение к выбранному элементу массива, k-максимальный элемент массива
                       
                       
                        protected
                          { Protected declarations }
                         function GetVivod(ID: Integer): String;
                         procedure SetActive(Value: Boolean);
                       
                        public
                          { Public declarations }
                         constructor Create(AOwner: TComponent); override;
                         destructor Destroy; override;
                         procedure Open;
                         procedure Close;
                         property Vivod[ID: Integer]: String read GetVivod;
                       
                        published
                          { Published declarations }
                          property Active: Boolean read FActive write SetActive;
                          property FileName: string read VFileName write VFileName;
                        end;
                       
                      procedure Register;
                       
                      implementation
                      function Tknyz.GetVivod(ID: Integer): String;
                      begin
                        if ((ID<0) or (ID>=k) ) then
                            begin
                            messageDlg('Вот так делать нельзя!', mtError, [mbOK],0);
                            end
                          else
                            begin
                            Result:=fData[ID];
                            end;
                      end;
                       
                      procedure Register;
                      begin
                        RegisterComponents('Standard', [Tknyz]);
                      end;
                       
                      constructor Tknyz.Create(AOwner: TComponent);
                      begin
                        inherited Create(AOwner);
                      end;
                       
                      procedure Tknyz.Open;
                       var
                        f: TextFile; // файл
                        fName: String[80]; // имя файла
                        buf: string[80]; // буфер для чтения из файла
                      begin
                        if Active then Exit;
                        fName:=FileName;
                        if Fname <> ''  then
                      begin
                        begin
                          k:=0;
                          AssignFile(f, fName);
                          //{$!-}
                          Reset(f); // открыть для чтения
                          //{$I+}
                       
                          if IOResult <> 0 then
                          begin
                            MessageDlg ('Ошибка доступа к файлу ' + fName,
                            mtError, [mbOk], 0); exit;
                          end;
                       
                          // Считываем файл и заполняем массив
                          while not EOF(f) do
                          begin
                            k:=k+1;
                            Setlength(fData, k);
                            readln(f, buf); // прочитать строку из файла
                            fData[k - 1]:= buf;
                       
                          end;
                        CloseFile(f); // закрыть файл
                       FActive:=true;
                        end
                      end;
                      end;
                       
                      procedure Tknyz.Close;
                      begin
                        Setlength(fData, 0);
                        FActive := false;
                      end;
                       
                      procedure Tknyz.SetActive(Value: Boolean);
                      begin
                        if FActive = Value then Exit;
                        if Value then Open
                         else Close;
                      end;
                      destructor Tknyz.Destroy;
                      begin
                         //уничтожим компонент
                         inherited;
                      end;
                       
                       
                       
                       
                      end.
                      емм... работает. попробуй пересобрать компонент. возможно среда видит старый образец компонента.
                      и еще я заметил что у тебя ни конструктор ни деструктор ничего не делают. посему их можно выбросить из кода.
                      и как по мне то нужно избавится от k:integer; вместо его лучше сделать свойство Count. в методе которого можно узнавать размер через Length

                      Добавлено
                      пс. и на досуге переглянь вот эту статейку Стандарты написания исходного кода в Delphi. придираюсь я насчет Соглашение об именованиях
                      Лучше себя сразу приучить к определенной стандартизации. Потом не придется переучиваться. (Во всех компаниях есть свой стандарт программирования. Который в своем большинстве состоит из набора подобных правил как в статейке)
                        а, да работает. Огромное спасибо;)

                        Добавлено
                        ок почитаю, я знаю что не соблюдаю правила в прошлом семестре прогу на Си сдавал когда препод в коде разобрался сказал что я сатанист
                          Цитата Rydj @
                          Доброго времени суток не могли Вы помочь разобраться почему не работает компонент на Delphi.
                          Задача: создать компонент в котором указываем путь к текстовому файлу с данными, он добавляет все данные в массив и потом позволяет получить выбранный пользователем элемент массива.

                          Кажется, вы пишете TStringList.. непонятно, почему это называется компонентом.
                          Оно визуальное? Или просто на форму кидается?
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0409 ]   [ 18 queries used ]   [ Generated: 20.04.24, 01:37 GMT ]