К списку форумов К списку вопросов
Не могу победить TCollection в BC++B 6... 8-(((
Романнист
02.08.2004 - 08:26
Создал класс (элемент коллекции) от TCollectionItem...
class PACKAGE TVertex : public TCollectionItem
{
  //Определение своих свойств и методов
  ...
  ...
  ...
}
Создал саму коллекцию от TCollection...
class PACKAGE TVertexCollection : public TCollection
{
}
Создал компонент от TTComponent...
class PACKAGE TVertexsList : public TComponent
{
}
...в который внедрил свойство TVertexCollection *FListVertexes ... (__property TVertexCollection *ListVertexes = { read=GetListVertexes, write=SetListVertexes };) и зарегистрировал его в конструкторе...
__fastcall TVertexsList::TVertexsList(TComponent* Owner)
  : TComponent(Owner)
{
  FListVertexes = new TVertexCollection(this, __classid(TVertex));
}
Замечу, что я не переписывал ни какие свойства и методы классов TCollection и TCollectionItem. Так вот, при конструировании объекта TVertexsList в режиме дизайнера свойство ListVertexes отлично редактируется, для него вызывается редактор свойств (как для тех же панелей в TStatusBar), задаю в инспекторе объектов значения свойств TVertex и т.д. Но... Но программно мне это сделать не удаётся... При написании такой конструкции ...
  VertexsList1->ListVertexes->Add();
  VertexsList1->ListVertexes->Items[0]->Caption = "12345";
... сообщает об ошибке, что Caption не член TCollectionItem...
Покопавшись в Инете, выяснил, что необходимо самостоятельно реализовывать функцию Add() для TVertexCollection... Верно ли это? и если да, то подскажите как! Заранее спасибо...
VaS
1 - 02.08.2004 - 09:30
Add() тут ни причем. Он создаст экземпляр нужного класса (TVertex). Дело в свойстве TCollection.Items, которое возвращает TCollectionItem. С этим поделать ничего нельзя - в VCL шаблоны не применяются. Стандартный подход - явное приведение типа:
(TVertex*)(VertexsList1->ListVertexes->Items[0]).Caption = ...
Либо реализация в TVertexCollection индексируемого свойства, возвращающего TVertex* для удобства в рантайме.
Романнист
2 - 02.08.2004 - 09:49
К сожалению с (TVertex*)(VertexsList1->ListVertexes->Items[0])->Caption = ... каменного цветка не выходит... Та же самая ошибка "Caption не член TCollectionItem"...
Романнист
3 - 02.08.2004 - 10:10
Применением dynamic_cast<TVertex*>(Graf1->ListVertexes->Items[0])->Caption = "12345"; удалось от такой ошибки избавиться... Проект запустился, но затем пытаясь тут же вывести MessageBox(NULL, dynamic_cast<TVertex*>(Graf1->ListVertexes->Items[0])->Caption.c_str(), "Проверка", MB_OK); получаем пустое сообщени, как будто ->Caption = ""; ...
Романнист
4 - 02.08.2004 - 10:11
Применением dynamic_cast<TVertex*>(VertexsList1->ListVertexes->Items[0])->Caption = "12345"; удалось от такой ошибки избавиться... Проект запустился, но затем пытаясь тут же вывести MessageBox(NULL, dynamic_cast<TVertex*>(VertexsList1->ListVertexes->Items[0])->Caption.c_str(), "Проверка", MB_OK); получаем пустое сообщени, как будто ->Caption = ""; ...
Романнист
5 - 02.08.2004 - 10:17
8-))) (3) пожалуйста, близко к серду не принимать 8-)))
VaS
6 - 02.08.2004 - 10:21
static_cast<TVertex*>(VertexsList1->ListVertexes->Items[0])->Caption = ...
VaS
7 - 02.08.2004 - 10:23
Походи по шагам метод Add() - зайдешь ли ты в конструктор TVertex.
Романнист
8 - 02.08.2004 - 10:24
Ошибок нет... И результата то же нет. Точнее результат такой же как и в (4).
Романнист
9 - 02.08.2004 - 10:30
Но...
  StatusBar1->Panels->Add();
  StatusBar1->Panels->Items[0]->Text = "12345";
Причём... У Panels две Add()... Первая от TStatusPanel *TStatusPanels::Add(), вторая от TColectionItem *TColection::Add(). И скорее всего при StatusBar1->Panels->Add(); работает именно первый вариант... То есть всё таки Add() своя у свойства Panels, компонента TStatusBar.
Романнист
10 - 02.08.2004 - 10:51
Нет... Попадаю стразу сюда...
TVertexCollection *__fastcall TVertexsList::GetListVertexes()
{
  return FListVertexes;
}
Романнист
11 - 02.08.2004 - 10:52
То есть... Объект TVertex при Add() у меня не инициализировался ка таковой...?
VaS
12 - 02.08.2004 - 10:53
А покажи саму коллекцию - где-то потерялся __classid элемента коллекции. Ибо вот такой код работает:
.
class PACKAGE TVertex : public TCollectionItem
{
public:
  String Caption;
};
{
  TCollection* C = new TCollection(__classid(TVertex));
  static_cast<TVertex*>(C->Add())->Caption = "45";
  static_cast<TVertex*>(C->Add())->Caption = "46";
  ShowMessage(static_cast<TVertex*>(C->Items[0])->Caption);
  ShowMessage(static_cast<TVertex*>(C->Items[1])->Caption);
}
Романнист
13 - 02.08.2004 - 10:58
Вот сама коллекция...
//---------------------------------------------------------------------------
#inсludе <basepch.h>
#pragma hdrstop
#inсludе "VertexCollection.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TVertexCollection::TVertexCollection(TPersistent* Owner, TMetaClass* ItemClass)
        : TCollection(ItemClass)
{
}
........................
//---------------------------------------------------------------------------
#ifndef VertexCollectionH
#define VertexCollectionH
//---------------------------------------------------------------------------
#inсludе <SysUtils.hpp>
#inсludе <Classes.hpp>
#inсludе "Vertex.h"
//---------------------------------------------------------------------------
class PACKAGE TVertexCollection : public TCollection
{
private:
protected:
public:
  __fastcall TVertexCollection(TPersistent* Owner, TMetaClass* ItemClass);
};
//---------------------------------------------------------------------------
#endif
Романнист
14 - 02.08.2004 - 11:03
Вот сам компонент...
#inсludе "VertexsList.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TGraf *)
{
  new TVertexsList(NULL);
}
//---------------------------------------------------------------------------
__fastcall TVertexsList::TVertexsList(TComponent* Owner)
  : TComponent(Owner)
{
  FListVertexes = new TVertexCollection(this, __classid(TVertex));
}
//---------------------------------------------------------------------------
namespace VertexsList
{
  void __fastcall PACKAGE Register()
  {
     TComponentClass classes[1] = {__classid(TVertexsList)};
     RegisterComponents("3G", classes, 0);
  }
}
//---------------------------------------------------------------------------
................
//---------------------------------------------------------------------------
#ifndef VertexsListH
#define VertexsListH
//---------------------------------------------------------------------------
#inсludе <SysUtils.hpp>
#inсludе <Classes.hpp>
#inсludе "Vertex.h"
#inсludе "VertexCollection.h"
//---------------------------------------------------------------------------
class PACKAGE TVertexsList : public TComponent
{
private:
  TVertexCollection *FListVertexes;
  void __fastcall SetListVertexes(TVertexCollection *value);
  TVertexCollection *__fastcall GetListVertexes();
protected:
public:
  __fastcall TVertexsList(TComponent* Owner);
__published:
  __property TVertexCollection *ListVertexes = { read=GetListVertexes, write=SetListVertexes };
};
//---------------------------------------------------------------------------
#endif
VaS
15 - 02.08.2004 - 11:19
Все верно. Вот код, все ок:
class PACKAGE TVertexCollection : public TCollection
{
public:
  __fastcall TVertexCollection(TPersistent* Owner, TMetaClass* ItemClass):
    TCollection(ItemClass){};
};
class PACKAGE TVertex : public TCollectionItem
{
public:
  String Caption;
};
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  TVertexCollection* C = new TVertexCollection(this, __classid(TVertex));
  static_cast<TVertex*>(C->Add())->Caption = "45";
  static_cast<TVertex*>(C->Add())->Caption = "46";
  ShowMessage(static_cast<TVertex*>(C->Items[0])->Caption);
  ShowMessage(static_cast<TVertex*>(C->Items[1])->Caption);
}
Романнист
16 - 02.08.2004 - 11:31
Урра! Заработало...!!! (... закричал кот Матроскин)... Спасибо большое. Беседа с Вами позволила взглянуть на свой код более внимательно, и ошибка нашлась!
Романнист
17 - 02.08.2004 - 11:33
Уважаемый VaS... Не согласились бы вы помочь мне ещё в одном вопросе, если Вас конечно не затруднит. То же бюсь, бьюсь и ни как не могу победить...

К списку вопросов на форуме Программирование

>>