Скачиваний:
40
Добавлен:
28.06.2014
Размер:
119 Кб
Скачать
☆

Идентификация типа объекта

Так как при передаче параметров объекты (Sender, Source, Target) имеют тип Tobject (базовый класс всех компонентов VCL – библиотеки), приходится определять, к какому классу в действительности принадлежит тот или иной компонент. Это можно сделать разными способами.

Приведение типа

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

Свойство Name есть у всех компонент библиотеки VCL и объявлено оно в классе TСomponent. Выражение ((TСomponent *)Sender)является приведением типа параметра Sender к типу указателя на объект класса TСomponent. Теперь можно узнать имя компонента:

Label1->Caption = ((TСomponent *)Sender) -> Name;

или

TComponent *Obj;

Obj = ((TСomponent *)Sender);

Теперь переменную Obj можно использовать как указатель на компонент:

Label1->Caption = Obj -> Name;

Часто программисту необходимо узнать является ли класс объекта потомком того класса, методы и свойства которого мы хотим использовать. Это можно проверить с помощью метода InheritsFrom, объявленного в TObject и возвращающего логический результат. Например, можно убедиться, что объект наследует свойства класса TWinControl:

if (Sender -> InheritsFrom(__classid(TWinControl)))

. . . ;

оператор __сlassid(classType) используется компилятором для генерации ссылки на указанный класс, в данном примере на классTWinControl.

Определение истинного класса объекта

В классе TObject определен метод ClassName(), возвращающий строку, содержащую действительный класс объекта. Имя класса можно, например, увидеть на экране:

Label1 -> Caption = Sender-> ClassName();

Или программно проверить принадлежность к интересующему нас классу:

if (String (Sender -> ClassName()) == “TShape”)

. . . ;

Для такой же проверки можно использовать функцию ClassNameIs, определенную в TObject и возвращающую результат типаbool.

If (Sender -> ClassNameIs(“TShape”) )

. . . ;

Иерархия классов объекта

Метод ClassParent,определенный в TObject позволяет определить класс, являющийся непосредственным предком класса заданного объекта. Если это объект классаTObject, то есть класс не имеет предков, то вернетсяNULL.

Для восстановления всей иерархии классов некоторого объекта следует использовать данный метод в цикле. На рис. 2.1 представлено главное окно приложения, которое в компоненте TreeView, предназначенном для отображения иерархических данных в виде дерева, отображает иерархию классов указанного объекта. Сами объекты (Edit1, Shape1, Button1 и Image1) также расположены в этом окне, а слева от них указаны имена классов объектов.

В программе использована технология Drag-and-Drop. Пользователь “перетаскивает” объект на компонент TreeView1 и, получив указатель на объект-источник информации, метод TreeView1DragDrop в цикле считывает имена классов объекта.

void __fastcall TForm1::TreeView1DragDrop(TObject *Sender, TObject *Source,

int X, int Y)

{

// Получение ссылки на класс объекта

TClass ClassRef = Source->ClassType();

if (Sender->ClassNameIs("TTreeView"))

{

// Получение указателя на объект TreeView1

TTreeView *pTV = (TTreeView *)Sender;

// Удаление предыдущей информации из TreeView1

while (pTV->GetNodeAt(0,0)!=NULL)

pTV->Items->Delete(pTV->GetNodeAt(0,0));

}

// Имена родительских классов добавляются в первый // узел дерева

while (ClassRef!=NULL)

{

TreeView1->Items->AddFirst(TreeView1->

GetNodeAt(0,0),ClassRef->ClassName());

ClassRef = ClassRef->ClassParent();

}

Label1->Caption ="Источник: " + (AnsiString)

(( TComponent *) Source)->Name;

}

Следующий код обработчика события OnDragOver определяет будет ли принят объект-источник компонентом TreeView1.

void __fastcall TForm1::TreeView1DragOver(TObject *Sender, TObject *Source,

int X, int Y, TDragState State, bool &Accept)

{ if (Source!=Sender)

Accept=true;

else

Accept=false;

}

Обработчик события OnEndDrag исходного объекта проверяет принят ли объект каким-либо целевым объектом..

Void __fastcallTForm1::ObjectEndDrag

(TObject*Sender, TObject *Target,

int X, int Y)

{

if (Target==NULL)

Label2->Caption="Нет целевого объекта";

else

Label2->Caption ="Приемник " + (AnsiString)

(( TComponent *) Target)->Name;

}