Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.08.04;
Скачать: CL | DM;

Вниз

Создание свойств типа   Найти похожие ветки 

 
Borealis   (2003-07-14 23:13) [0]

У моего компонента есть объектное свойство. Когда оно происходит от класса TPersistent всё прекрасно работает, но если оно наследуется от TComponent (или позже), то подсвойства, почему-то, перестают записыватся в dfm-файл.
Наверно я смутно объяснил, поэтому вот пример:
...
type
TMyColors = class(TPersistent)
private
FColor1: TColor;
FColor2: TColor;
published
property Color1: TColor read FColor1 write FColor1;
property Color2: TColor read FColor2 write FColor2;
end;

TSuperPuperComponent = class(TComponent)
private
FColors: TMyColors;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Colors: TMyColors read FColors write FColors;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents("Samples", [TSuperPuperComponent]);
end;

{ TSuperPuperComponent }

constructor TSuperPuperComponent.Create(AOwner: TComponent);
begin
inherited;
FColors:=TMyColors.Create;
end;

destructor TSuperPuperComponent.Destroy;
begin
FColors.Free;
inherited;
end;
...

В таком варианте всё работает, но если в верхней строке: TMyColors = class(TPersistent), TPersistent заменить на TComponent (и подправить конструктор), то подсвойста Color1 и Color2, свойства Colors, компонента TSuperPuperComponent не записываются в dfm-файл.

Что же мне сделать, что-бы эти свойства записывались?


 
Rouse_ ©   (2003-07-15 01:50) [1]

А зачем TComponent для данной реализации?
Может быть смысл шире?

Желаю успехов


 
Юрий Зотов ©   (2003-07-15 04:42) [2]

По умолчанию свойство типа TComponent среда считает ссылкой на внешний компонент, поэтому она записывает только саму эту ссылку (считая, что компонент, на который она ссылается и так уже где-то записывается).

Чтобы записывалась не ссылка, а сам компонент, нужно в классе TSuperPuperComponent заместить метод DefineProperties, а в нем определить методы чтения и записи свойства Colors. Ну и, конечно, написать сами эти методы. Примеры см.в VCL.


 
Borealis   (2003-07-20 10:55) [3]

> Rouse_ © (15.07.03 01:50)
> А зачем TComponent для данной реализации?
> Может быть смысл шире?

Совершенно верно. В данной реализации от TComponent больше вреда чем пользы. Данный пример показывает, так сказать, корень зла - TPersistent и любые его потомки (кроме TComponent) ведут себя вполне адекватно, но не TComponent и его потомки. На самом деле, моя компонента должна вобрать в себя несколько (уже готовых) компонент, сама же их создавать, освобождать, отображать в инспекторе объектов, позволять редактировать (в том же инспекторе объектов) любые свойства этих компонент (но не позволять подменять сами компоненты на похожие уже лежащие на форме!), ну и естественно сохранять изменения в "*.dfm"-файле в виде "объект в объекте" (то есть как с TPersistent).


> Юрий Зотов © (15.07.03 04:42)
> ...
> нужно в классе TSuperPuperComponent заместить метод DefineProperties

Это единственный выход? Может есть более естественный способ избавиться от этого глюка (как я его называю :), скажем както зарегистрировать эти свойства чтобы они считались внутренними объектами (а значит подлежащими сохранению в "*.dfm"-файле)?

Если же всё же это единственный выход, то как это реализовать? Я уже весь извёлся - перепробовал все методы типа ReadXXX, WriteXXX у TWriter и TReader - все прекрасно работают кроме ReadComponent и WriteComponent! На все мои эксперименты Delphi говорит или "Stream read error", или "Access violation...", или вобще молча выгружается.

Где ошибка в нижеприведённом варианте?

procedure TSuperPuperComponent.LoadCompProperty(Reader: TReader);
begin
Reader.ReadComponent(FColors);
end;

procedure TSuperPuperComponent.StoreCompProperty(Writer: TWriter);
begin
Writer.WriteComponent(FColors);
end;

procedure TSuperPuperComponent.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty("Colors", LoadCompProperty, StoreCompProperty, True);
end;


 
Романов Р.В. ©   (2003-07-20 11:14) [4]

Есть способ проще начиная с 6 дельфи, тока я его не помню :)) (т.к. пользуюсь D5).
Суть его в том что у вложенного компонента устанавливается специальный флаг кажелся в свойстве ComponentStyle, после этого компонент сохраняется в dfm его владельцем.
PS: В TComponent по моему появился новый метод который устанавливает это свойство.


 
Borealis   (2003-07-20 11:50) [5]


> Романов Р.В. © (20.07.03 11:14)
> Есть способ проще начиная с 6 дельфи...


Ура! Ура! Ты гений! :))
Действительно в D6 у класса TComponent появилось новое свойство ComponentStyle, и метод SetSubComponent как раз решающий мою проблему :)
Достаточно в конструкторе сказать:
constructor TSuperPuperComponent.Create(AOwner: TComponent);
begin
inherited;
FColors:=TMyColors.Create(Self);
FColors.SetSubComponent(True);
end;

И опля: свойство Colors уже сохраняется в dfm-файле :)

ps. Уже ради спортивного интереса мне всё таки интересно почему у меня не заработали WriteComponent и ReadComponent?



Страницы: 1 вся ветка

Текущий архив: 2003.08.04;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.014 c
3-10146
Вит
2003-07-11 16:40
2003.08.04
Здравствуйте, мастера. Вопрос по хранимой процедуре


3-10103
anatolyk
2003-07-11 22:47
2003.08.04
Автоинкр. поля в MSSQL


3-10098
Spawn
2003-07-13 07:38
2003.08.04
Не могу вносить данные в НД


1-10291
Alex300
2003-07-22 09:33
2003.08.04
Проблема с курсором


1-10259
Andy BitOff
2003-07-21 14:47
2003.08.04
Запрет выполнения любых сообщений?