Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Вниз

Сохранение объекта в dfm   Найти похожие ветки 

 
mikeflat ©   (2004-04-23 13:40) [0]

Есть объект, например такой
TMyObject = class(TComponent)
 private
   FObj: TCustomObjects;
   FStr: string;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
 published
   property Obj: TCustomObjects read FObj write FObj;
   property Str: string read FStr write FStr;
 end;
у него есть published свойство Obj - объект-наследник TComponent.
Вопрос: как сохранить этот объект в формате dfm? Свойство Str сохраняется без проблем, а вот Obj - не хочет!


 
mikeflat ©   (2004-04-23 13:40) [0]

Есть объект, например такой
TMyObject = class(TComponent)
 private
   FObj: TCustomObjects;
   FStr: string;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
 published
   property Obj: TCustomObjects read FObj write FObj;
   property Str: string read FStr write FStr;
 end;
у него есть published свойство Obj - объект-наследник TComponent.
Вопрос: как сохранить этот объект в формате dfm? Свойство Str сохраняется без проблем, а вот Obj - не хочет!


 
MBo ©   (2004-04-23 13:44) [1]

DefineProperties


 
MBo ©   (2004-04-23 13:44) [1]

DefineProperties


 
mikeflat ©   (2004-04-23 14:02) [2]

Да понятно, что DefineProperties, а что писать в методах чтения и записи, просто WriteComponent не идет, пример из help работает только на запись - не читает, да и вообще получается коряво. Чо делать-то?


 
mikeflat ©   (2004-04-23 14:02) [2]

Да понятно, что DefineProperties, а что писать в методах чтения и записи, просто WriteComponent не идет, пример из help работает только на запись - не читает, да и вообще получается коряво. Чо делать-то?


 
oso   (2004-04-23 14:44) [3]

По умолчанию св-ва типа компонент (в отличие от простых
персистентов) рассматриваются как
ссылки на внешние компоненты и сохраняются в виде имён.

В Д6 появился специальный флаг csSubComponent,
позволяющий сохранять дочерние компоненты,
сохраняя все их св-ва (см SetSubComponent).

С помощью DefineProperties это так просто не сделаешь, -  
парсер не переварит (Если установлен режим текстовой ДФМ).
Можно, конечно, сохранять вс-ва по одному или DefineBinaryProperties, но это всё геморрой.

Попробуй SetSubComponent, если версия позволяет.


 
oso   (2004-04-23 14:44) [3]

По умолчанию св-ва типа компонент (в отличие от простых
персистентов) рассматриваются как
ссылки на внешние компоненты и сохраняются в виде имён.

В Д6 появился специальный флаг csSubComponent,
позволяющий сохранять дочерние компоненты,
сохраняя все их св-ва (см SetSubComponent).

С помощью DefineProperties это так просто не сделаешь, -  
парсер не переварит (Если установлен режим текстовой ДФМ).
Можно, конечно, сохранять вс-ва по одному или DefineBinaryProperties, но это всё геморрой.

Попробуй SetSubComponent, если версия позволяет.


 
mikeflat ©   (2004-04-23 16:42) [4]

Но ведь сама форма все красиво сохраняет!


 
mikeflat ©   (2004-04-23 16:42) [4]

Но ведь сама форма все красиво сохраняет!


 
oso   (2004-04-23 16:59) [5]

Там совсем другая схема сохранения.
Компоненты сохраняются не как паблишед-свойства,
а как дочерние компоненты своими родителями.

Причём при загрузке из ДФМ компоненты всегда создаются
(За исключением визуального наследования - ffInheritance),
а у тебя надо загрузить св-ва уже созданного компонента.


 
oso   (2004-04-23 16:59) [5]

Там совсем другая схема сохранения.
Компоненты сохраняются не как паблишед-свойства,
а как дочерние компоненты своими родителями.

Причём при загрузке из ДФМ компоненты всегда создаются
(За исключением визуального наследования - ffInheritance),
а у тебя надо загрузить св-ва уже созданного компонента.


 
Матлабист   (2004-04-23 18:01) [6]

TCustomObjects должен быть порожден от TPersistent. Иначе --- define properties


 
Матлабист   (2004-04-23 18:01) [6]

TCustomObjects должен быть порожден от TPersistent. Иначе --- define properties


 
mikeflat ©   (2004-04-24 14:34) [7]

Ребята, стоит унаследовать TMyObject от TWinControl, а TCustomObject от TControl - все работает отлично, правда автоматически прописываются ище свойства Left,Top, With и Height. Все бы хорошо, но они мешают.
Есть еще какие-нибудь варианты?


 
mikeflat ©   (2004-04-24 14:34) [7]

Ребята, стоит унаследовать TMyObject от TWinControl, а TCustomObject от TControl - все работает отлично, правда автоматически прописываются ище свойства Left,Top, With и Height. Все бы хорошо, но они мешают.
Есть еще какие-нибудь варианты?


 
Игорь Шевченко ©   (2004-04-24 18:28) [8]

Например так.

 TFOPObject = class(TComponent)
 private
   FTransAmount: Double;
   FFOPName: String;
 public
   constructor CreateFOP(AOwner: TComponent; const AFOPName: string; ATransAmount: Double);
   constructor CreateLike (AOwner: TComponent; Source: TFopObject);
 published
   property FOPName: string read FFOPName write FFOPName;
   property TransAmount: Double read FTransAmount write FTransAmount;
 end;

 TFOPList = class(TList)
 private
   function GetItems(I: Integer): TFOPObject;
 public
   procedure Clear; override;
   function HasFop (const AName: String): Boolean;
   property Items[I: Integer]: TFOPObject read GetItems; default;
 end;

 TTransObject = class(TComponent)
 private
   FFOPList : TFOPList;
   procedure ReadFOPS (Reader: TReader);
   procedure WriteFOPS (Writer: TWriter);
..................
 protected
   procedure DefineProperties(Filer : TFiler); override;
..................
 public
   constructor Create (AOwner: TComponent); override;
   destructor  Destroy; override;
   property FOPList : TFOPList read FFOPList;
............
 end;

....
procedure TTransObject.DefineProperties(Filer: TFiler);

 function DoWriteFOP: Boolean;
 begin
   Result := FFOPList.Count > 0;
 end;

begin
 inherited;
 Filer.DefineProperty("FOPS", ReadFOPS, WriteFOPS, DoWriteFOP);
.......
end;

procedure TTransObject.ReadFOPS(Reader: TReader);
begin
 FFOPList.Clear;
 Reader.ReadListBegin;
 while not Reader.EndOfList do
   FFOPList.Add(Reader.ReadComponent(nil));
 Reader.ReadListEnd;
end;

procedure TTransObject.WriteFOPS(Writer: TWriter);
var
 I: Integer;
begin
 Writer.WriteListBegin;
 for I:=0 to Pred(FFOPList.Count) do
   Writer.WriteComponent(FFOPList[I]);
 Writer.WriteListEnd;
end;



 
Игорь Шевченко ©   (2004-04-24 18:28) [8]

Например так.

 TFOPObject = class(TComponent)
 private
   FTransAmount: Double;
   FFOPName: String;
 public
   constructor CreateFOP(AOwner: TComponent; const AFOPName: string; ATransAmount: Double);
   constructor CreateLike (AOwner: TComponent; Source: TFopObject);
 published
   property FOPName: string read FFOPName write FFOPName;
   property TransAmount: Double read FTransAmount write FTransAmount;
 end;

 TFOPList = class(TList)
 private
   function GetItems(I: Integer): TFOPObject;
 public
   procedure Clear; override;
   function HasFop (const AName: String): Boolean;
   property Items[I: Integer]: TFOPObject read GetItems; default;
 end;

 TTransObject = class(TComponent)
 private
   FFOPList : TFOPList;
   procedure ReadFOPS (Reader: TReader);
   procedure WriteFOPS (Writer: TWriter);
..................
 protected
   procedure DefineProperties(Filer : TFiler); override;
..................
 public
   constructor Create (AOwner: TComponent); override;
   destructor  Destroy; override;
   property FOPList : TFOPList read FFOPList;
............
 end;

....
procedure TTransObject.DefineProperties(Filer: TFiler);

 function DoWriteFOP: Boolean;
 begin
   Result := FFOPList.Count > 0;
 end;

begin
 inherited;
 Filer.DefineProperty("FOPS", ReadFOPS, WriteFOPS, DoWriteFOP);
.......
end;

procedure TTransObject.ReadFOPS(Reader: TReader);
begin
 FFOPList.Clear;
 Reader.ReadListBegin;
 while not Reader.EndOfList do
   FFOPList.Add(Reader.ReadComponent(nil));
 Reader.ReadListEnd;
end;

procedure TTransObject.WriteFOPS(Writer: TWriter);
var
 I: Integer;
begin
 Writer.WriteListBegin;
 for I:=0 to Pred(FFOPList.Count) do
   Writer.WriteComponent(FFOPList[I]);
 Writer.WriteListEnd;
end;



 
Юрий Зотов ©   (2004-04-24 23:20) [9]

> mikeflat ©   (24.04.04 14:34) [7]

Посмотрите, как это сделано в связке TDataSet-TField или в TMenu-TMenuItem. Вам нужно сделать так же.

> Игорь Шевченко ©   (24.04.04 18:28) [8]

IMHO, такая схема сохранения может привести к проблемам с визуальным наследованием форм, содержащих TTransObject.


 
Юрий Зотов ©   (2004-04-24 23:20) [9]

> mikeflat ©   (24.04.04 14:34) [7]

Посмотрите, как это сделано в связке TDataSet-TField или в TMenu-TMenuItem. Вам нужно сделать так же.

> Игорь Шевченко ©   (24.04.04 18:28) [8]

IMHO, такая схема сохранения может привести к проблемам с визуальным наследованием форм, содержащих TTransObject.


 
Игорь Шевченко ©   (2004-04-25 00:12) [10]

Юрий Зотов ©   (24.04.04 23:20)

Я каюсь, этот компонент не предназначается для форм, это сохранение неких данных в поле базы данных типа BLOB :)

Если можно обрисовать проблему с наследованием, был бы признателен :)


 
Игорь Шевченко ©   (2004-04-25 00:12) [10]

Юрий Зотов ©   (24.04.04 23:20)

Я каюсь, этот компонент не предназначается для форм, это сохранение неких данных в поле базы данных типа BLOB :)

Если можно обрисовать проблему с наследованием, был бы признателен :)


 
Юрий Зотов ©   (2004-04-25 08:22) [11]

> Игорь Шевченко ©   (25.04.04 00:12) [10]

Запись списка компонентов в DFM идет при единственном условии Count > 0. Но, если форма наследует компонент TTransObject от своего предка и в списке по сравнению с этим предком ничего не менялось, то ведь и в этом случае писать список в DFM тоже незачем. А если что-то менялось - то писать надо только изменения.

Здесь же переписка происходит всегда и полностью - что нарушает наследование ресурсов. Если, например, в форме-предке я изменю какое-то свойство в одном из компонентов TFOPObject, то на потомке это не отразится никак - а ведь должно было бы.

"Правильный" механизм сохранения реализуется перекрытием методов GetParentComponent, SetParentComponent, HasParent, GetChildParent, GetChildren и других. При этом компонент- контейнер становится "родителем" своих внутренних компонентов, а их Owner"ом остается форма. Как раз так, например, и работает связка TDataset-TField (и все нормально сохраняется, и все нормально наследуется).

Но реально, конечно, все зависит от задачи. Если визуальное наследование заведомо исключено, то и незачем городить огород.


 
Юрий Зотов ©   (2004-04-25 08:22) [11]

> Игорь Шевченко ©   (25.04.04 00:12) [10]

Запись списка компонентов в DFM идет при единственном условии Count > 0. Но, если форма наследует компонент TTransObject от своего предка и в списке по сравнению с этим предком ничего не менялось, то ведь и в этом случае писать список в DFM тоже незачем. А если что-то менялось - то писать надо только изменения.

Здесь же переписка происходит всегда и полностью - что нарушает наследование ресурсов. Если, например, в форме-предке я изменю какое-то свойство в одном из компонентов TFOPObject, то на потомке это не отразится никак - а ведь должно было бы.

"Правильный" механизм сохранения реализуется перекрытием методов GetParentComponent, SetParentComponent, HasParent, GetChildParent, GetChildren и других. При этом компонент- контейнер становится "родителем" своих внутренних компонентов, а их Owner"ом остается форма. Как раз так, например, и работает связка TDataset-TField (и все нормально сохраняется, и все нормально наследуется).

Но реально, конечно, все зависит от задачи. Если визуальное наследование заведомо исключено, то и незачем городить огород.



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

Форум: "Основная";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.05 c
14-1082109682
Voland2000
2004-04-16 14:01
2004.05.09
Nokia 8110-forever


7-1079636270
Константин
2004-03-18 21:57
2004.05.09
Автозапуск


14-1082364804
WondeRu
2004-04-19 12:53
2004.05.09
Понял почему остальные комнаты форума пустуют!


7-1079620750
Falendysh
2004-03-18 17:39
2004.05.09
OLE Container проблема


14-1082441697
Vlad Oshin
2004-04-20 10:14
2004.05.09
Делаю книгу. Как сделать лучше?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский