Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 24.03.2009, 00:01   #1
Oburec
Пользователь
 
Регистрация: 20.03.2009
Сообщений: 33
По умолчанию сохранение/загрузка вложенных компонент в dfm

Есть компонент сParentComponent (наследник TWinControl) который хранит ссылку на список вложеных компонентов (наследники TComponent). Метод GetChildren переопределен
Код:
procedure сParentComponent.GetChildren(Proc: TGetChildProc;Root: TComponent);
begin
 for i := 0 to SubComponents.Count-1 do
 begin
    Proc(TComponent(subcomponents.Items[i]));
 end;
end;
таким образом, список компонентов сохраняется в dfm, но!!! 2 раза. Первый - как вложенные компоненты у сParentComponent, второй - на уровне компонентов формы.
Как оставить сохранение компонентов только у сParentComponent. Как потом при загрузке собрать эти вложенные компоненты обратно в список subcomponents (TList) у cParentControl.
Owner-ом субкомпонетов является форма.
Oburec вне форума
Старый 24.03.2009, 00:16   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Тот кусок кода, который вы привели, никак не поможет пониманию сути вашего вопроса.
Покажите, как вы создаете наследника.
mihali4 вне форума
Старый 24.03.2009, 20:08   #3
Oburec
Пользователь
 
Регистрация: 20.03.2009
Сообщений: 33
По умолчанию

Цитата:
Сообщение от mihali4 Посмотреть сообщение
Тот кусок кода, который вы привели, никак не поможет пониманию сути вашего вопроса.
Покажите, как вы создаете наследника.
То, что не поможет я догадывался. просто не знаю какую часть кода выложить. чтоб помогло...
у редактора компонента cParentComponent переопределен метод Edit, по вызову которого создается форма. На форме имеется кнопка, которая позволяет добавлять субкомпоненты. Код нажатия на кнопку такой:
Код:
procedure TObjExplorerDlg.AddObjBtnClick(Sender: TObject);
var obj:cSubComponent;
begin
  obj:=nil;
  if Assigned(Designer) then
  begin
    obj:=cSubComponent(Designer.CreateComponent(cSubComponent, ParentComponent , -1, -1, -1, -1));
  // basegl.InsertComponent(obj); // Если раскоментарить, то сохраняется правильно(1 раз и как
    //субкомпонент), но не знаю как потом загрузить правильно. Кроме того при таком создании
    //компонент не отображается в списке Structures (утилита среды Delphi).
    basegl.subcomponents.Add(obj); // добавление созданного компонента в список вложеных компонент
    Designer.Modified;
  end;
end;

Последний раз редактировалось Oburec; 24.03.2009 в 20:10.
Oburec вне форума
Старый 25.03.2009, 21:58   #4
Oburec
Пользователь
 
Регистрация: 20.03.2009
Сообщений: 33
Сообщение

Выкладываю пример созданный alexBlack-ом (за что ему огромное спасибо). с незначительными доработками. В данном примере создается ParentComponent, на котором размещаются два контрола. Иерархия компонентов правильно отображается в IDE-ом structure и правильно сохраняется в форму.
Для активации примера необходимо проинсталировать компонент, кинуть на форму Tbutton и два раза по нему кликнуть
Код:
unit TestUnit;

interface

uses Classes, Controls, ExtCtrls, StdCtrls, DesignIntf, DesignEditors,
     ToolsAPI, Dialogs, ubaseglcomponent;

type
   TParentComponent = class(twincontrol)
   private
      FList : TList;
   protected
      procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
   public
      constructor Create(AOwner:TComponent); override;
   end;

   TSubComponent = class(TLabel) // Если унаследовать от чистого Tcontrol то компоненты не правильно отобразятся в Structures
   end;

   TButtonEditor = class(TComponentEditor)
     procedure Edit; override;
   end;

procedure Register;

implementation

procedure Register;
begin
   RegisterComponentEditor(TButton, TButtonEditor);
   RegisterComponents('Samples', [TParentComponent, TSubComponent]);
end;

constructor TParentComponent.Create(AOwner:TComponent);
begin
   inherited Create(AOwner);
   FList := TList.Create;
end;

procedure TButtonEditor.Edit;
var P:TParentComponent;
    obj:tsubcomponent;
begin
   if Designer = nil then exit;
   P := Designer.CreateComponent(TParentComponent, Designer.Root, 10, 10, 10, 10) as TParentComponent;
   obj:=tsubcomponent(Designer.CreateComponent(TSubComponent, P, 10, 10, 10, 10));
   obj.Parent:=p;//Если закоментарить работать не будет
   P.flist.add(obj);
   obj:=tsubcomponent(Designer.CreateComponent(TSubComponent, P, 10, 10, 10, 10));
   obj.Parent:=p;//Если закоментарить работать не будет
   P.flist.add(obj);
end;

procedure TParentComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
var I: Integer;
    Control: TSubComponent;
begin
  for I := 0 to FList.Count - 1 do
  begin
    Control := TSubcomponent(FList[i]);
    if Control.Owner = Root then
     Proc(Control);
  end;
end;
end.
Однако лично у меня не совсем этот случай . Дело в том, что мои SubComponent-ы не визуальные, следовательно не Tcontrol, а TComponent. А следовательно не имеют свойства parent. В коде отмечено две строки в которых это свойство используется. При закоментаривании этих строк форма перестает правильно сохраняться, субкомпоненты сохраняются дважды (суть проблемы в первом посте). Вопрос остается - как побороть сохранение компонента на уровне формы
Код:
object form1: TForm
  object ParentComponent1: TParentComponent
    object SubComponent1: TsubComponent
    end
  end
  Object SubComponent1: TsubComponent
  end
end
Цветом отмечено лишнее

Последний раз редактировалось Oburec; 25.03.2009 в 22:47.
Oburec вне форума
Старый 25.03.2009, 23:28   #5
Oburec
Пользователь
 
Регистрация: 20.03.2009
Сообщений: 33
По умолчанию

Итак решение найдено. У TComponent есть два динамических метода, которые по умолчанию всегда возвращают одно и тоже. HasParent - возвращает false, GetParentComponent - возвращает nil.
Перекрывая эти методы, и вернув true в HasParent и вернув ссылку на ParentComponent в GetParentComponent все будет удачно сохраняться в dfm файл и будет правильно отображаться в structure окошке.

Последний раз редактировалось Oburec; 25.03.2009 в 23:48.
Oburec вне форума
Старый 26.03.2009, 11:30   #6
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Про назначение кнопки "Правка" не догадываетесь?
Значит - ни читали правила раздела, значит - нарываетесь на штраф...
mihali4 вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Загрузка/сохранение рисунков Marsik Помощь студентам 20 20.11.2008 18:09
Загрузка и сохранение в файл rainbow Общие вопросы Delphi 16 27.09.2008 11:35
HRGN сохранение-загрузка? Comer_Jus Общие вопросы Delphi 5 21.05.2008 20:12
Сохранение и загрузка информации Slash Общие вопросы Delphi 9 04.02.2007 22:01