Конференция "Компоненты" » Сериализация [D7, WinXP]
 
  • nick_van_rijn © (21.07.08 17:05) [0]
    Подскажите к вопросу о сохранении коипонентов в поток. Класс а- наследник от TComponent. Класс b- наследник от а.
    Пишу сериализацию, WriteComponent. Сохраняется только данные экземпляра класса а. Тут же пишу сериализацию для Form1 и там четко сохраняется все дерево классов. В чем может быть проблема?
  • Сергей М. © (21.07.08 19:53) [1]
    см.

    TPersistent.DefineProperties/DefineProperty
    TComponent.GetChildren

    Чудеса скрыты именно там)
  • nick_van_rijn © (21.07.08 21:59) [2]
    fix-up позднее замещение имен указателями. Defineproperty определяют эти свойства. Getchildren для вызова метода предка. где же чудеса?
  • Игорь Шевченко © (21.07.08 22:00) [3]
    Кусок из моего кода с сериализацией

    type
      TFoo = class(TComponent)
     protected
       // Метод TComponent перекрыт для сохранения всего дерева в потоке.
       // Если этот метод не перекрывать, сохраняется только текущий элемент.
       procedure GetChildren (Proc: TGetChildProc; Root: TComponent); override;
       // Метод TComponent перекрыт для восстановления иерархии дерева при чтении
       // из потока. Если этот метод не перекрывать, подчиненность элементов нару-
       // шается.
       procedure SetParentComponent (Value: TComponent); override;
    public
       // Метод TComponent перекрыт для восстановления иерархии дерева при чтении.
       // TODO: Как выяснилось, перекрыт зря, может быть, есть смысл убрать.
       function GetParentComponent: TComponent; override;
       // Метод TComponent перекрыт для восстановления иерархии дерева при чтении.
       // TODO: Как выяснилось, перекрыт зря, может быть, есть смысл убрать.
       function HasParent: Boolean; override;
    end;

  • Сергей М. © (21.07.08 22:11) [4]

    > где же чудеса?


    Чудеса - в виртуализации  и перекрытии.


    > Getchildren для вызова метода предка


    Чавой-то ?!
  • nick_van_rijn © (21.07.08 22:36) [5]
    Игорь Шевченко спасибо за код, вникну.
  • Игорь Шевченко © (21.07.08 23:55) [6]
    и, соответственно реализация:

    procedure TFoo.GetChildren(Proc: TGetChildProc;
     Root: TComponent);
    var
     I: Integer;
    begin
     inherited;
     for I := 0 to Pred(inherited ComponentCount) do
       Proc(inherited Components[I]);
    end;

    procedure TFoo.SetParentComponent(Value: TComponent);
    var
     I: Integer;
    begin
     inherited;
     if Value <> nil then
       for I:=0 to Pred(Value.ComponentCount) do
         if Value.Components[I] = Self then
           Exit;
       if Owner <> nil then
         Owner.RemoveComponent (Self);
       Value.InsertComponent(Self);
    end;

    function TFoo.GetParentComponent: TComponent;
    begin
     if IAmRoot = 0 then //Мое внутреннее свойство для корневого элемента
       Result := inherited GetParentComponent
     else
       Result := Owner;
    end;

    function TFoo.HasParent: Boolean;
    begin
     Result := not IAmRoot; //Мое внутреннее свойство для корневого элемента
    end;

  • Юрий Зотов © (22.07.08 07:30) [7]
    Методы, связанные с Parent- и Children-компонентами, влияют только тогда, когда эти самые Children вообще имеются. Это случаи, аналогичные пунктам меню, полям и т.п. - то есть, когда владельцем компонента является форма, но в то же время он как бы "принадлежит" некоему другому компоненту-контейнеру.

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

    > nick_van_rijn ©   (21.07.08 17:05)  
    > В чем может быть проблема?

    Если у Вас именно такой случай, то см. предыдущие ответы. Если нет - показывайте код, без него ничего конкретного сказать нельзя.
  • nick_van_rijn © (22.07.08 10:02) [8]
    В моем случае это как раз дерево с достаточно глубокими вложениями. Получается что для моего примера мне необходимо перекрыть метода класса а и перевставлять каждого потомка самостоятельно?

     Owner.RemoveComponent (Self);
      Value.InsertComponent(Self);

  • Юрий Зотов © (22.07.08 10:16) [9]
    > nick_van_rijn ©   (22.07.08 10:02) [8]

    А как бы Вы сами ответили на свой вопрос, не имея никакой другой информации, кроме двух строчек псевдокода, неизвестно к чему относящегося?

    Неужели непонятно, что конкретное обсуждение может состояться при наличии конкретного кода?

    Иначе что обсуждать-то? Общие концепции VCL? Так они и без обсуждений известны.
  • nick_van_rijn © (22.07.08 10:35) [10]
    спасибо [6] ответ на все мои вопросы.
  • thenomad © (03.03.09 21:32) [11]
    Появилась проблемка, связанная с данным вопросом:

    type
     TEDAChild = class;

     TEDAParent = class(TComponent)
       constructor Create(AOwner:TComponent);override;
       procedure GetChildren(Proc: TGetChildProc; Root: TComponent);override;
     private
       FChild:TEDAChild;
     published
       property Child:TEDAChild read FChild write FChild;
     end;

     TEDAChild = class(TComponent)
       FEDAParent : TEDAParent;
       function GetParentComponent:TComponent;override;
     end;

     procedure Register;

    implementation

    constructor TEDAParent.Create(AOwner:TComponent);
    begin
     inherited Create(AOwner);
     Child := TEDAChild.Create(Self);
     Child.FEDAParent := Self;
    end;

    procedure TEDAParent.GetChildren(Proc: TGetChildProc; Root: TComponent);
    begin
     Proc(Child);
    end;

    function TEDAChild.GetParentComponent:TComponent;
    begin
     Result := FEDAParent;
    end;

    procedure Register;
    begin
     RegisterComponents('EDA',[TEDAParent]);
    end;

    Initialization
     RegisterClass(TEDAChild);

    end.



    В Design-time, если поместить компонент на форму и перейти в "View as text" а потом обратно (View as Form) - возникает ошибка. Что делаю не так???
 
Конференция "Компоненты" » Сериализация [D7, WinXP]
Есть новые Нет новых   [134465   +63][b:0][p:0.002]