![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
RTTI. Как обратиться к потомку, заведомо не зная его класс? [D7]
mfender © (2010-10-18 14:44:00)Вот такая ситуация:
type
TCustomEditor = class(TPanel)
private
FPriorCtrl: TDBSpinEdit;
FArchiveCtrl: TDBCheckBox;
FFieldCtrl: TWinControl;
public
constructor Create(AOwner: TComponent); override;
procedure Positioning;
end;
TStringEditor = class(TCustomEditor)
private
FFieldCtrl: TDBEdit;
public
constructor Create(AOwner: TComponent); override;
end;
TMemoEditor = class(TCustomEditor)
private
FFieldCtrl: TDBMemo;
public
constructor Create(AOwner: TComponent); override;
end;
implementation
constructor TCustomEditor.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPriorCtrl := TDBSpinEdit.Create(Self);
FPrior.Parent := Self;
FArchiveCtrl := TDBCheckBox.Create(Self);
FArchiveCtrl.Parent := Self;
end;
constructor TStringEditor.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FFieldCtrl := TDBEdit.Create(Self);
FFieldCtrl.Parent := Self;
end;
constructor TStringEditor.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FFieldCtrl := TDBMemo.Create(Self);
FFieldCtrl.Parent := Self;
end;
procedure TCustomEditor.Positioning;
begin
FPriorCtrl.Left := .....
FPriorCtrl.Top := .....
<et cetera…>
end;
Код сокращён до степени общего понимания. на самом деле там есть ещё published свойства read-only для контролов на панели, есть TDataSource и TDataSet.
Где-то сбоку я создаю в зависимости от надобности либо TStringEditor, либо TMemoEditor. Составляющие контролы созданы, теперь нужно их правильно позиционировать на панели.
Но вот беда: я знаю достоверно, что все они TCustomEditor, но с этим знанием я никогда в жизни не доберусь до FFieldCtrl - в TCustomEditor он не создан (Access Violation). Значит нужно вызывать Positioning из соответствующего наследыша.
Можно, вобщем-то, сверяться с классом путём case of, но это быстрый пример, на самом деле у меня таких сборных компонентов там порядка дюжины, отличающихся только одним FFieldCtrl.
Вот уже и так и сяк голову сломал - застрэлите меня, но я окончательно запутался в попытках при помощи RTTI обратиться к Positioning через наследника TCustomEditor, который мне заранее не известен.
Заранее благодарен за помощь.
Юрий Зотов (2010-10-18 17:26:00) [1]> RWolf © (18.10.10 15:36) [4]
Ну не то, чтобы уж совсем расстрелять, но совет и правда не из лучших.
> mfender (18.10.10 15:00) [2]
type
TCustomEditor = class(TPanel)
private
FPriorCtrl: TDBSpinEdit;
FArchiveCtrl: TDBCheckBox;
FFieldCtrl: TWinControl;
public
constructor Create(AOwner: TComponent); override;
procedure Positioning; virtual; abstract;
end;
В каждом потомке перекрываем метод Positioning. Теперь обращаться к нему можно откуда угодно, в том числе и из предка тоже.
jack128_ (2010-10-18 17:13:00) [2]
> Что мне это даст? Я ж всё равно не смогу обратиться к нему
> из потомка, не зная потомка.
имелось в виду "обратиться к нему из предка, не зная потомка" ?
а зачем, если мона перекрыть метод?
Игорь Шевченко (2010-10-18 15:56:00) [3]RWolf © (18.10.10 15:36) [4]
Расстрелять
RWolf (2010-10-18 15:36:00) [4]var child:TCustomEditor;
…
if child is TStringEditor then
(child as TStringEditor).DoSomething;
Игорь Шевченко (2010-10-18 15:35:00) [5]
> Но вот беда: я знаю достоверно, что все они TCustomEditor,
> но с этим знанием я никогда в жизни не доберусь до FFieldCtrl
>
значит надо сделать свойство FFieldCtrl у TCustomEditor, ссылающееся на виртуальный метод GetFieldCtrl, перекрытый в потомках
mfender (2010-10-18 15:00:00) [6]
> сделай Positioning виртуальным и перекрой его в потомках.
Что мне это даст? Я ж всё равно не смогу обратиться к нему из потомка, не зная потомка.
jack128_ (2010-10-18 14:55:00) [7]сделай Positioning виртуальным и перекрой его в потомках.