Создание VCL-компонента.

 
0
 
C++
ava
PRIZRAK001 | 07.03.2006, 19:11
 Здравствуйте.

Создаю VCL компонент, имеющий вложенные свойства. Вот примерный код.

Класс, описывающий сложное свойство.
// NestedProp.h

class TNestedProp : public TPersistent
   {
   private:

      int FProp;

   public:

      __fastcall TNestedProp();

   __published:

      __property int Prop = {read = FProp, write = FProp}; // свойство внутри свойства
};
// NestedProp.cpp

__fastcall TNestedProp :: TNestedProp() : TPersistent()
   {
   FProp = 3;  // задаём значение по умолчанию
   }

Сам компонент. 
 // MyComp.h

#include "NestedProp.h"

class PACKAGE TMyComp : public TPanel
   {
      TNestedProp* FNestedProp;

   public:

      __fastcall TMyComp(TComponent* Owner);
      __fastcall ~TMyComp();      

   __published:

      __property TNestedProp* NestedProp = {read = FNestedProp};
};
 
// MyComp.cpp

__fastcall TMyComp::TMyComp(TComponent* Owner)
        : TPanel(Owner)
   {
   FNestedProp = new TNestedProp();
   }

__fastcall TMyComp::~TMyComp()
   {
   delete FNestedProp;
   }

Кладём компонент на форму и пишем следующий код.
void __fastcall TForm1::FormShow(TObject *Sender)
   {
   ShowMessage(MyComp1->NestedProp->Prop); // выводит на экран значение Prop
   }

Проблема заключается в том, что невозможно изменить значение Prop при помощи инспектора объектов. Точнее, его можно изменить, но какое бы значение мы не задавали, функция ShowMessage всегда будет выводить «3». Т.е. изменения внесённые в режиме проектирования, не переносятся на работающую программу. Полагаю, это связано с тем, что значение свойства Prop не сохраняется в файле *.dfm.

Как заставить работать всё нормально? 
Ответы (3)
ava
Vyacheslav | 07.03.2006, 19:36 #
 Скорее всего ,  все дело в том, что Вы перекрываете загруженное значени в теле конструктора.
Для начала уберите присвоение в конструкторе и посмотрите, что получится. 
ava
PRIZRAK001 | 08.03.2006, 01:33 #
 
Цитата (Vyacheslav @  7.3.2006,  19:36 findReferencedText)
Для начала уберите присвоение в конструкторе и посмотрите, что получится. 

Попробовал (закоментировал "FProp = 0") - в результате стал выдавать всё время "0", а не то что хочеться.

Дело в том, что VCL-компонент инициализируется, и когда кладешь его на форму, и когда запускаешь приложение. И каждый раз вызывается конструктор. Поэтому, чтобы значения свойств не потерялись, они сохраняются в файле *.dfm, соотвествующей формы. А затем восстанавливаются. Но такая штука, срабатывает только для простых типов (int, double) и для стандартных билдеровских (TFont). А вот как сохранить свои типы???.........
 
ava
PRIZRAK001 | 08.03.2006, 15:50 #
 Решение найдено!!! Нужно писать метод write. Если его нет, то данные не сохраняются в файле *.dfm.

Вот как можно сделать

// NestedProp.h

class TNestedProp : public TPersistent
   {
   private:

      int FProp;

   public:

      __fastcall TNestedProp();

      virtual void __fastcall Assign(TPersistent* Value);

   __published:

      __property int Prop = {read = FProp, write = FProp};
   };

// NestedProp.cpp

void __fastcall TNestedProp :: Assign(TPersistent* Value)
   {
   TNestedProp* NestedProp = dynamic_cast<TNestedProp*>(Value);

   if (NestedProp)
      FProp = NestedProp->FProp;
   else
      throw Exception("Can't assign " + Value->ClassName() + " to " + ClassName());
   }

// MyComp.h

#include "NestedProp.h"

class PACKAGE TMyComp : public TPanel
   {
      TNestedProp* FNestedProp;

      void __fastcall SetNestedProp(TNestedProp* Value);

   public:

      __fastcall TMyComp(TComponent* Owner);
      virtual __fastcall ~TMyComp();

   __published:

      __property TNestedProp* NestedProp = {read = FNestedProp, write = SetNestedProp};
   }; 

// MyComp.cpp

void __fastcall TMyComp :: SetNestedProp(TNestedProp* Value)
   {
   FNestedProp->Assign(Value);
   } 

 
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить