Конференция "Компоненты" » Как получить в компоненте список классов проекта? [D7, WinXP]
 
  • Megavolt_old (02.09.11 13:02) [0]
    Можно ли сделать так чтобы компонент после бросания на форму каким то образом имел список всех классов проекта?

    Т.е. очень охота чтобы в инспекторе объектов можно было выбрать только что написанный клас о котором сам компонент на момент написания ничего не знал? Или знал бы только класс предка?

    Иными словами хочу чтобы мой компонент мог исспользовать любой потомок некого базового класса. Желательно чтобы этот класс не нужно было устанавливать как компонент.
  • DimaBr © (03.09.11 23:51) [1]
    Нельзя в дизайнере отобразить класс не проинсталированный в системе
  • Cobalt © (05.09.11 08:44) [2]
    Если надо использовать "любой класс" - для этого достаточно объявить свойство типа ссылка-на-класс
    Другой вопрос - как ты им собираешься пользоваться. если ты не знаешь что это за класс? Должны же быть у тебя какие-то требования к этому классу.
  • MegaVolt_old (05.09.11 11:26) [3]
    >Нельзя в дизайнере отобразить класс не проинсталированный в системе

    Даже через ToolsAPI?

    >Должны же быть у тебя какие-то требования к этому классу.

    Ага. Наследники некого базового класса.
  • DimaBr © (05.09.11 11:52) [4]
    То что набрано в текстовом редакторе ещё не класс, а просто ТЕКСТ.
    ToolsAPI работает с существующими классами, а не написанными на бумаге
  • DimaBr © (05.09.11 11:58) [5]
    В инспекторе класс выбрать нельзя, можно выбрать экземпляр класса.
    Составить список классов проекта в дизайнере можно, для этого нужно иметь собственный парсер PAS файлов, которому скормить все файлы проекта.
    Объясните подробнее свою задачу, для чего всё это нужно, и что вы собираетесь редактировать в инспекторе
  • MegaVolt_old (05.09.11 12:04) [6]
    >То что набрано в текстовом редакторе ещё не класс, а просто ТЕКСТ.

    Текст. Но при этом например как только я написал end у класса он появляется в списке слева. Т.е. IDE его уже увидел и уже занёс в некий свой список. Я не прав?

    >ToolsAPI работает с существующими классами, а не написанными на бумаге

    Вот например Class Browser из состава GExperts показал пустой класс только что мной добавленный в проект и нигде не зарегистрированный. Т.е. всё же то что я хочу возможно.

    Другой вопрос могу ли я в своём компоненте в Design Time исспользовать ToosAPI? Если да то осталось только выдрать с исходников GExpert нужный код.
  • MegaVolt_old (05.09.11 12:38) [7]
    Мдя... Посмотрел GExpert так они там парсят исходные файлы.... Неожиданно оказалось :(

    Хотя дельфи же как то с списках классов показывает только что написанный класс... Вот только похоже доступа к этой инфе нету :(
  • DimaBr © (05.09.11 12:58) [8]

    procedure TClassItem.LoadClass(const FileName: string);
    var
     EditorStream: TMemoryStream;
     Parser: TmEPTokenList;
     Buf: array[0..30] of char;
     p1, i, j: Integer;
     ObjectInfo: TBrowseClassInfoCollection;
     LocalEditReader: TEditReader;
    begin
     if not IsDprOrPas(FileName) or IsInc(FileName) then
       Exit;

     LocalEditReader := TClassList(Collection).EditRead;
     LocalEditReader.FileName := FileName;
     LocalEditReader.Reset;

     EditorStream := TMemoryStream.Create;
     try
       LocalEditReader.SaveToStream(EditorStream);
       EditorStream.Position := EditorStream.Size;
       FillChar(Buf, 23, 0);
       EditorStream.WriteBuffer(Buf, 23);
       EditorStream.Position := 0;
       Parser := TmEPTokenList.Create;


    Дальше и читать не стал - СОБСТВЕННЫЙ ПАРСЕР
  • DimaBr © (05.09.11 13:00) [9]
    > Хотя дельфи же как то с списках классов показывает только что написанный класс...

    В Delphi - тоже свой парсер, класса ещё не существует, и через ToolsAPI не достучаться
  • MegaVolt_old (05.09.11 13:24) [10]
    То что в дельфи собственный парсер я и не сомневался... Я думал к результатам его работы можно достучаться через ToolsApi.

    В принципе выдрать парсер с GExpert тоже вариант но какой то уж очень громоздкий....
  • DimaBr © (05.09.11 13:32) [11]
    Лучше расскажите что вы хотите сделать
  • MegaVolt_old (05.09.11 14:22) [12]
    Хочу чтобы в компоненте была возможность использовать только что написанные классы. Т.е. написал класс, подцепил его тут же, настроил свойства :)
  • DimaBr © (05.09.11 14:36) [13]
    У класса нельзя настроить свойства, можно у экземпляра класса
  • MegaVolt_old (05.09.11 15:02) [14]
    Экземпляр класса будет создавать компонент в Design Time по имени класса.
  • DimaBr © (05.09.11 23:46) [15]
    Нельзя создать то, чего не существует.
    И потом, допустим реализовалась ваша несбыточная мечта, и можно создавать классы в дизайнере из только что написанного кода. Тогда вы, например, бросаете компонент на форму и в коде конструктора пишите Left := 0, при этом компонент прыгнул на форме к левому краю, переводим курсор и добавляем 9 (получилось Left := 90), и компонент прыгнул уже немного правее. Далее пишем в коде цикл (for i := 0 to 1000 do Left := Random(10000)) и компонент начинает летать по форме. Это уже какой-то не DesignTime, а RunTime получается. Далее пишем ( while true do;) и после ";" Delphi умирает. Всё, нужно снимать процесс в диспетчере задач.

    Пересмотрите свою задачу. Если вам действительно нужно RunTime в дизайнере, стоит посмотреть в сторону FastReport с собственным дизайнером и скриптом.
  • MegaVolt_old (06.09.11 10:51) [16]
    Признаю идея была хороша но нереализуема :((((((

    Мне RunTime в дизайнере не нужен.

    Что нужно:

    Компонент визуальный наследник от виртуального ListView с OwnerDraw.

    Хотелось бы:
    - иметь в каждой колонке коллекцию классов унаследованных от некого базового. Каждый класс отвечает за отрисовку и реакцию на собиытия отдельного кусочка колонки. Например чекбокс + текст это уже коллекция из двух компонентов.

    Сейчас пока реализовал коллекцию из базовых классов и в дизайн тайме можно задать им положение и некоторые общие параметры но само собой раз класс отвечающий за настоящее рисование не задан то в дизайнтайме не получается настроить все свойства и обработчики. А хотелось бы.

    Вот что есть пока в дизайн тайме: http://pixs.ru/showimage/ListViewpn_2260731_2920380.png
    Первая колонка три элемента коллекции (второй невидимый), третья один.

    Вот очень хочется чтобы вместо красных стандартных квадративок был реальный компонент с реальной отрисовкой и свойствами.

    Готов регистрировать классы :)) Только вот вопрос регистрация класса регистрирует его где? В пользовательском пакете или как?
  • DimaBr © (06.09.11 11:07) [17]
    У вас в каждой строчке первого столбца отдельный редактор ? Или весь первый столбец одинаковые редакторы ?
  • MegaVolt_old (06.09.11 12:54) [18]
    В первой строчке на картинке 3 редактора но впринципе может быть сколько нужно.
  • MegaVolt_old (06.09.11 12:57) [19]
    В первом столбце на картинке 3 редактора но впринципе может быть сколько нужно.

    Только это скорее не редакторы а некие элементы отображения(управления)
  • DimaBr © (06.09.11 14:03) [20]
    Я ничего не понимаю, У вас есть столбец, в нём 3 редактора ? В каждой строчке одинаковые 3 редактора ? Или в каждой строчке разные редакторы (по типу) ???
  • MegaVolt_old (06.09.11 14:21) [21]
    >У вас есть столбец, в нём 3 редактора ?

    В том примере что я выложил в первом столбце 3 редактора во втором 1. Вообще же может быть в каждом столбце сколько угодно редакторов. Столбцы друг от друга не зависят.

    В кажом стролбце могут быть как одинаковые так и разные редакторы.

    Т.е. сейчас к каждому столбцу прикручен экзампляр класса унаследованного от TCollection.
  • MegaVolt_old (07.09.11 16:14) [22]
    Стало понятнее?
  • DimaBr © (08.09.11 00:16) [23]
    Начните с случая попроще: 1 столбец - 1 редактор.

    TBaseEditor = class
     protected
        procedure Draw; virtual;abstract; // наследник реализует прорисовку
        procedure Edit; virtual;abstract; // наследник реализует редактирование
        function GetValue: variant; virtual;abstract; // наследник реализует получение значения
        procedure SetValue(Value: variant);virtual;abstract; // наследник реализует установку значения
    end;

  • MegaVolt_old (08.09.11 10:22) [24]
    Вопрос скорее не про то как сделать редактор а как его грамотно подсунуть компоненту в дизайнтайме и настроить его свойства.
  • DimaBr © (08.09.11 12:59) [25]

    // перечень редакторов
    TMyEditors = (eCheck, eEdit, eCyrrency, eButton);

    // базовый редактор
    TMyBaseEditor = class(TPersistent)

    end;

    TMYComponent = class(TComponent)
    published
     property Editor: TBaseEditor read fEditor;
     property TypeEditor: TMyEditors read fTypeEditor write SetTypeEditor;
    end;

    procedure SetTypeEditor(Value: TMyEditors);
    var Old: TBaseEditor;
    begin
     if fTypeEditor = Value then Exit;
     Old := Editor; // запоминаем старый редактор
     try
       case Value of // в зависимости от типа создаём новый
          eCheck: fEditor := TMyCheckEditor.Create();
          eEdit: fEditor := TMyEditEditor.Create();
          ..............
       end;
     finally
       FreeAndNil(Old); // уничтожаем старый редактор
       fTypeEditor := Value;
     end;
    end;

  • MegaVolt_old (08.09.11 13:30) [26]
    Как делать со списком понятно. А как делать если появился новый редактор? Которого не было на момент написания компонента?

    Т.е. когда список TMyEditors = (eCheck, eEdit, eCyrrency, eButton); расширен новым редактором?
  • DimaBr © (08.09.11 23:35) [27]
    Значит ввести текстовый список ('eCheck', 'eEdit', 'eCyrrency', 'eButton'), плюс регистрация нового редактора. Тогда свойство TypeEditor будет выглядеть так
    property TypeEditor: string read fTypeEditor write SetTypeEditor;

    var fRegisterEditorList: TStringsList;

    procedure RegistrEditor(TypeEditor: string; ClassEditor: TBaseEditor);
    begin
     if not Assigned(fRegisterEditorList) then fRegisterEditorList := TStringList.Create;
     if fRegisterEditorList.IndexOf(TypeEditor) >= 0 then Exit;
     fRegisterEditorList.AddObject(TypeEditor,ClassEditor);
    end;

    procedure SetTypeEditor(Value: string);
    var Old: TBaseEditor;
        n: integer;
        f: boolean;
    begin
    if fTypeEditor = Value then Exit;
    Old := Editor; // запоминаем старый редактор
    try
      f := false;
      for i := 0 to fRegisterEditorList.Count-1 do
         if SameText(fRegisterEditorList[i],Value) then begin
            fEditor := TMyBaseEditor(fRegisterEditorList.Objects[i]).Create();
            f := true;
            Break;
         end;
      if not f then Exit;
    finally
      FreeAndNil(Old); // уничтожаем старый редактор
      fTypeEditor := Value;
    end;
    end;

    initialization
     RegistrEditor('eCheck',TMyCheckEditor);
     RegistrEditor('eEdit',TMyEditEditor);
    end.

    // ===============================
    // новый модуль
    initialization
     RegistrEditor('eButton',TMyButtonEditor);
    end.


  • MegaVolt_old (08.09.11 23:41) [28]
    !!! Передавать имя класса через строку я не догадался... Всё искал как же получить список доступных в дизайн тайме эдиторов.

    Бальшущее спасибо.
  • DimaBr © (09.09.11 02:16) [29]
    Для свойства можно организовать редактор свойства, который и будет показывать список доступных редакторов (тавтология какая-то).
 
Конференция "Компоненты" » Как получить в компоненте список классов проекта? [D7, WinXP]
Есть новые Нет новых   [118682   +10][b:0][p:0.003]