![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как проверить реализацию интерфейса и привести к нему?
Kolan © (2007-11-09 10:26:00)Здравствуйте,
проведите лик. без. плз. :)
Итак есть два потомка двух разных классов.
TStructureTreeView = class(TTreeView)
private
FBlockID: Integer;
FGroupID: Integer;
public
property BlockID: Integer read FBlockID write FBlockID;
property GroupID: Integer read FGroupID write FGroupID;
end;
TCustomStructureIDLabel = class(TCustomStructureLabel)
private
FBlockID: Integer;
FGroupID: Integer;
public
property BlockID: Integer read FBlockID write FBlockID;
property GroupID: Integer read FGroupID write FGroupID;
end;
Изменить предков нельзя.
Мне надо пройтись в цикле и найти все объекты його и 2ого классов. Так как предки у них разные, то ессно приходится написать две похожие операции:
function TCardDataView.FindStructureTreeView(GroupID: Integer;
LookForInComponent: TComponent): TStructureTreeView;
var
I: Integer;
begin
Result := nil;
if Assigned(LookForInComponent) then
begin
for I := 0 to LookForInComponent.ComponentCount 1 do
if (LookForInComponent.Components[I] is TStructureTreeView)then
if TStructureTreeView(LookForInComponent.Components[I]).GroupID = GroupIDthen
begin
Result := TStructureTreeView(LookForInComponent.Components[I]);
Exit;
end;
end;
function TCardDataView.FindGroupNameLabel(GroupID: Integer;
LookForInComponent: TComponent): TGroupNameLabel;
var
I: Integer;
begin
Result := nil;
if Assigned(LookForInComponent) then
begin
for I := 0 to LookForInComponent.ComponentCount 1 do
if (LookForInComponent.Components[I] is TGroupNameLabel)then
if TGroupNameLabel(LookForInComponent.Components[I]).GroupID = GroupIDthen
begin
Result := TGroupNameLabel(LookForInComponent.Components[I]);
Exit;
end;
end;
end;
Как видно разница только в приведении типов.
IMyInt = interface
property BlockID: Integer read FBlockID write FBlockID;
property GroupID: Integer read FGroupID write FGroupID;
end;
(*)Описание интерфейса схемотичное, должнобыть понятно, имхо.
Вот если бы сделать так, чтобы оба собжевых класса реализовывали интерфейсIMyInt.
И тут вопрос №1: Что надо перекрыть, чтобы любой класс(а не потомок TInterfacedObject) мог реализоввывать интерфейс?
Затем можнобыло бы сделать 1 процедуру типа:
if (LookForInComponent.Components[I] is IMyInt) then
if IMyInt(LookForInComponent.Components[I]).GroupID = GroupID then
Только ессно так не получится. А как надо?
Ega23 (2007-11-09 14:07:00) [1]
> Для компоненттов - это не верно...
Я не знаю, надо в реализацию посмотреть.
jack128_ (2007-11-09 14:03:00) [2]
> Когда счётчик ссылок станет равным нулю, объект грохнется
> автоматически.
Для компоненттов - это не верно...
Kolan (2007-11-09 12:26:00) [3]> Когда счётчик ссылок станет равным нулю, объект грохнется
> автоматически.
Ну я знаю. Не с интерфейсами я работал, просто обычно выстраивал свою иерархию отTInterfacedObject'а.
Ega23 (2007-11-09 12:15:00) [4]
> Понял понял. Сенкс. Разобрался.
Смотри с ними, аккуратнее.
Когда счётчик ссылок станет равным нулю, объект грохнется автоматически.
Kolan (2007-11-09 12:07:00) [5]> Или я вопроса не понял?
Понял понял. Сенкс. Разобрался.
Джо (2007-11-09 11:55:00) [6]> [11] Kolan © (09.11.07 11:51)
> А все наследники TComponent же поддерживают интерфейсы так?
Да, у всех наследников TComponent уже реализована троица
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
Или я вопроса не понял?
Kolan (2007-11-09 11:54:00) [7]> зачем IInterface реализовывать?
Вопрос не понял.
ЗЫ Именно так как вы написали и хочу сделать. В к чему вопрос?
Slym (2007-11-09 11:52:00) [8]зачем IInterface реализовывать?
IMyInt = interface
['{96A80746-A018-4CBE-B029-F3A464545006}']
function GetBlockID:Integer;
procedure SetBlockID(const Lalue:integer);
function GetGroupID:Integer;
procedure SetGroupID(const Lalue:integer);
property BlockID: Integer read GetBlockID write SetBlockID;
property GroupID: Integer read GetGroupID write SetGroupID;
end;
а потом if LookForInComponent.Components[I].GetInterface(IMyInt,obj) then
obj.GroupID:= GroupID;
Kolan (2007-11-09 11:51:00) [9]А все наследники TComponent же поддерживают интерфейсы так?
Джо (2007-11-09 11:49:00) [10]> [7] Kolan © (09.11.07 11:42)
> > if Obj.GetInterface(IMyIntf,Intf) then
>
>
> Так да?
>
> procedure TForm1.BitBtn1Click(Sender: TObject);
> var
> MyInt: IMyInt;
> begin
> if Form1.GetInterface(IMyInt, MyInt) then
> MyInt.Test;
> end;
Ага.
b z (2007-11-09 11:49:00) [11]
> Ega23 © (09.11.07 11:07) [6]
так в except никогда не попадет » Джо: » Попадет.
С диагнозом 'Interface not supported'.
Kolan (2007-11-09 11:46:00) [12]Гы, так вот зачем нужен GUID в интерфейсе :) Раньше не блыо в нём необходимости
Kolan (2007-11-09 11:42:00) [13]> if Obj.GetInterface(IMyIntf,Intf) then
Так да?
procedure TForm1.BitBtn1Click(Sender: TObject);
var
MyInt: IMyInt;
begin
if Form1.GetInterface(IMyInt, MyInt) then
MyInt.Test;
end;
Ega23 (2007-11-09 11:07:00) [14]
var
imi : IMyInterface;
try
imi := Object as IMyInterface;
except
Не поддерживает
end;
:)
Джо (2007-11-09 11:06:00) [15]if Obj.GetInterface(IMyIntf,Intf) then
Kolan (2007-11-09 10:59:00) [16]> Это уж как тебе надо.
Ок, с этим всё понятно. Как теперь пройтись по списочку, узнать поддерживатеся ли интерфейс и если да, то обратиться к объекту через этот интерфейс?
Ega23 (2007-11-09 10:34:00) [17]
> И скопипастиьть их из TInterfacedObject, так?
Это уж как тебе надо. Лично я внутри _AddRef и _Release счётчик сылок в -1 держу, если не хочу, чтобы объект автоматом разрушилсо.
Kolan (2007-11-09 10:30:00) [18]> Определить три метода
И скопипастиьть их из TInterfacedObject, так?
Джо (2007-11-09 10:29:00) [19]> Что надо перекрыть, чтобы любой класс(а не потомок TInterfacedObject)
> мог реализоввывать интерфейс?
Определить три метода
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;