C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Хочу добавить пару свойств в TColumn
cirius
Отправлено: 15.07.2004, 19:08


Ученик-кочегар

Группа: Участник
Сообщений: 6



В доработанном DBGrid надо чтобы в колонках хранилась доп. инфа.
Делаю так, к пакету где лежит мой грид добавляю следующий юнит:

Unit1.h

class TTreeColumn : public TColumn
{
private:
..................
новые поля
..................
protected:
public:
__published:
.........................
новые свойства
.........................
};

//-----------------------------------------------------------------------------
class TTreeDBGridColumns : public TDBGridColumns
{
private:
TTreeColumn __fastcall GetColumn(int Index);
void __fastcall SetColumn(int Index, TTreeColumn *Value);
protected:
public:
__property TTreeColumn* Items[int Index] = {read=GetColumn, write=SetColumn};
__published:
};

=====================================================
Unit1.cpp


TTreeColumn __fastcall TTreeDBGridColumns::GetColumn(int Index)
{
return Items[Index];
}

void __fastcall TTreeDBGridColumns::SetColumn(int Index, TTreeColumn *Value)
{
Items[Index]->Assign(Value);
}

На последнюю строчку ругается так:
[C++ Fatal Error] TreeColumn.cpp(18): F1001 Internal code generator error
Кто подскажет что не так или может можно как-то гораздо проще это сделать?
AVC
Отправлено: 16.07.2004, 08:20


Ветеран

Группа: Модератор
Сообщений: 1583



Для начала можно попробовать так (код не тестировался):
CODE

class TTreeDBGridColumns : public TDBGridColumns
{
private:
TList *FList;
TTreeColumn __fastcall GetColumn(int Index);
void __fastcall SetColumn(int Index, TTreeColumn *Value);
protected:
public:
__fastcall TTreeDBGridColumns (void) {FList = new TList();}
__fastcall virtual ~TAxRecord (void)
{ TTreeColumn *pt;
 for (int i = FList->Count; i > 0; i--)
  { pt = (TTreeColumn*)(FList->Items[i-1]);
    delete pt;
  }
 FList->Clear();
}

__property TTreeColumn* Items[int Index] = {read = GetColumn, write = SetColumn};
__published:
};



TTreeColumn __fastcall TTreeDBGridColumns::GetColumn(int Index)
{
if (!this) return NULL;
if (idx < 0 || idx >= FList->Count) return NULL;
return (TTreeColumn*)(FList->Items[idx]);
}

void __fastcall TTreeDBGridColumns::SetColumn(int Index, TTreeColumn *Value)
{
if (!this) return;
if (idx < 0 || idx >= FList->Count) throw ....;
TTreeColumn *pt = (TTreeColumn*)(FList->Items[idx]);
pt->Assign(Value);
}


Метод Assign должен быть определен корректно, не забыть методы Add и Delete.

А теперь вопрос.
Как вы заставите наследника DBGrid работать с вашим TTreeColumn ? Для этого вам придется переписать большинство методов DBGrid для создания колонок.
olegenty
Отправлено: 16.07.2004, 10:30


Ветеран

Группа: Модератор
Сообщений: 2412



Не совсем так. Грид будет ориентироваться на наследника TCollection, а там перекрыть надо всего пару методов (если вести речь о создании/удалении колонок и устанвке их свойств). А вот в рантайме — надо смотреть, я не в курсе. Я с коллекциями работаю, но не трогая визуальных компонентов. Надо сказать, создав первую свою коллекцию (коллекцию элементов TStrings, для хранения всех служебных запросов в одном месте и доступа к ним через коллекцию — ну ОЧЕНЬ удобно), я поразился простоте и универсальности работы сей удобной штуки (связки наследника TCollectionItem и наследника TOwnedCollection).
AVC
Отправлено: 16.07.2004, 13:25


Ветеран

Группа: Модератор
Сообщений: 1583



Я имел ввиду, что сколько ни далать наследников от TColumn, базовый TDBGrid всегда будет управлять только бызовым TColumn (в частности выделять под него память). Т.е. если насдедник TColumn не имеет новых свойств, а только методы — проблем нет. Если есть свойства то нужно очень возиться с наследником TDBGrid.
PS. А я люблю TList.
olegenty
Отправлено: 16.07.2004, 14:09


Ветеран

Группа: Модератор
Сообщений: 2412



Да и я тоже, но DesignTime редактор для наследников TCollection уже есть. А я коллекциями пользуюсь только в том случае, когда мне что-то надо "коллекционировать" в DesignTime.

Нет, память под наследника коллекции будет выделять коллекция, с этим тоже проблем быть не должно, оно там всё на метаклассы завязывается и работает корректно.
AVC
Отправлено: 16.07.2004, 14:43


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE
там всё на метаклассы завязывается

Спасибо. Принял к сведению. Попробую. Меня смущал TCustomDBGrid::(private TDBGridColumns*) FColumns.
cirius
Отправлено: 16.07.2004, 23:40


Ученик-кочегар

Группа: Участник
Сообщений: 6



Спасибо, взял на заметку. Тут начальство поменяло приоритеты, так что пока прийдется это дело отложить.
Кстати вопрос: а что такое метаклассы?
olegenty
Отправлено: 17.07.2004, 07:53


Ветеран

Группа: Модератор
Сообщений: 2412



Зачитай инфу по TMetaClass smile.gif
olegenty
Отправлено: 17.07.2004, 07:56


Ветеран

Группа: Модератор
Сообщений: 2412



2AVC
QUOTE

Меня смущал TCustomDBGrid::(private TDBGridColumns*) FColumns


вот имено это место-то и надо будет переписывать — вставлять сюда коллекцию наследников TColumn. При этом, все имена свойств наследника невредно оставить прежними, и лишь добавить свежие, для расширения функциональности.
AVC
Отправлено: 22.07.2004, 13:22


Ветеран

Группа: Модератор
Сообщений: 1583



2olegenty
(Извиняюсь за поздний ответ. Из за проблемы с подсветкой тема ушла из области видимости)
QUOTE

QUOTE
Меня смущал TCustomDBGrid::(private TDBGridColumns*) FColumns

вот имено это место-то и надо будет переписывать


А так как нет возможности перекрыть privat'ный член родительского класса — будем пытаться перкрыть необходимый минимум функций которые с ним работают. Т.е. смотри мое собщение номер 1.

Вернуться в Вопросы программирования в C++Builder