Форум: "Компоненты";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];
ВнизСоздание компонента Найти похожие ветки
← →
vladmk (2005-12-01 10:16) [0]Суть вопроса в следующем:
Имеется несколько компонентов(Компон1, Компон2 .. КомпонN) которые имеют общего предка и у них одинаковые названия у public и published методов и свойств, но разная их реализация.
Вопрос: как создать компонент к которому в design-time и run-time можно подключать один из компонентов (Компон1, Компон2 .. КомпонN) и работать с их методами и свойствами.
Заранее благодарен всем ответившим.
← →
Юрий Зотов © (2005-12-01 23:08) [1]Если компоненты 1..N и их общий предок выполнены правильно, то так:
type
TMyComp = class(...)
private
FCompRef: TОбщийПредок;
procedure SetCompRef(const Value: TОбщийПредок);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
published
property CompRef: TОбщийПредок read FCompRef write SetCompRef;
end;
procedure TMyComp.SetCompRef(const Value: TОбщийПредок);
begin
if FCompRef <> Value then
begin
if FCompRef <> nil then
RemoveFreeNotification(FCompRef);
FCompRef := Value;
if FCompRef <> nil then
FreeNotification(FCompRef)
end
end;
procedure TMyComp.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (Operation = opRemove) and (AComponent = FCompRef) then
FCompRef := nil
end;
← →
FH (2005-12-03 13:17) [2]А если у них нет общего предка, только одинаковые методы и свойства?
← →
jack128 © (2005-12-03 14:56) [3]FH (03.12.05 13:17) [2]
А если у них нет общего предка,
Объявить интерфейс, реализовать его во всех Comp1..CompN, а твоем новом компоненте описать published свойство интерфейсного типа..
← →
FH (2005-12-03 15:45) [4]Спасибо, а как объявить интерфейс?
← →
FH (2005-12-03 16:11) [5]и как реализовать его во всех Comp1..CompN
Прошу прощения за дебильный вопрос, никогда не сталкивался с такими вещами. В справке нашел вот этоtype
IMyInterface = interface
procedure P1;
procedure P2;
end;
TMyClass = class(TObject, IMyInterface)
FMyInterface: IMyInterface;
property MyInterface: IMyInterface read FMyInterface implements IMyInterface;
end;
var
MyClass: TMyClass;
MyInterface: IMyInterface;
begin
MyClass := TMyClass.Create;
MyClass.FMyInterface := ... // some object whose class implements IMyInterface
MyInterface := MyClass;
MyInterface.P1;
end;
но как-то слабо помогает.
у меня первый компонент - наследник TIdUdpServer, второй будет наследником TIdTCPServer...
← →
jack128 © (2005-12-03 16:35) [6]Ну например:
ИнтерфейсISchemeItemControl = interface(IUnknown)
["{73861986-6815-46F1-8CBF-538AC822C42E}"]
property SchemeItem: TSchemeItem read GetSchemeItem;
end;
Классы, реализующие этот интерфейс
TSchemeTransportNodeControl = class(TDesignControl, ISchemeItemControl) // Это наследник TComponent, поэтому реализовать IUnknown не нужно.
protected
{ ISchemeItemControl }
function GetSchemeItem: TSchemeItem;
end;
TSchemeWayConnector = class(TControlConnector, IUnknown, ISchemeItemControl) // Это "просто" класс, нужно реализовать IUnknown
protected
{ IUnknown }
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
{ ISchemeItemControl }
function GetSchemeItem: TSchemeItem;
end;
И еще, для нормальной работы с интерфейсами нужно четко представлять себе, что такое посчет ссылок и как он реалиован в Дельфи. Что то мне кажется, что тебе он не нужен, значит те придется его проигноривать. Иначе огребешь немерено глюков..
← →
jack128 © (2005-12-03 16:35) [7]Сорри, опечатка
ISchemeItemControl = interface(IUnknown)
["{73861986-6815-46F1-8CBF-538AC822C42E}"]
function GetSchemeItem: TSchemeItem;
property SchemeItem: TSchemeItem read GetSchemeItem;
end;
← →
FH (2005-12-03 16:48) [8]Это примерно понятно, у меня они все будут наследниками TComponent, с IUnknown заморачиваться не буду.
Сперва описываю интерфейс IMyServer, у него будет несколько процедур и событий. Потом переписываю мой первый компонент, как class(TIdUDPServer, IMyServer), у него все методы должны совпадать с тем, ч то я написал в IMyServer. А дальше? Компонент, в котором я смогу в runtime поменять TMyIdUDPServer на TMyIdIdServer?
← →
jack128 © (2005-12-03 17:19) [9]IMyServer = interface
["{4CD6D36D-B404-4513-B6FA-21931B2F3F88}"]
end;
TSomeComp = class(TComponent)
private
FMyServer: IMyServer;
published
property MyServer: IMyServer read FMyServer write FMyServer;
end;
var
SomeComp: TSomeComp;
begin
...
SomeComp.MyServer := MyIdUDPServerVar;
...
SomeComp.MyServer := MyIdIdServerVar;
..
...
end;
← →
FH (2005-12-03 17:28) [10]спасибо
А что там насчет глюков?
Это должно работать?
← →
jack128 © (2005-12-03 19:41) [11]Например в этом коде, если ты уничтожишь сначала MyIdIdServerVar, а потом SomeComp, то в SomeComp.Destroy получишь AV. Чтобы его избежать, нужно перед уничтожением MyIdIdServerVar обнилить свойство MyServer.
← →
FH (2005-12-09 19:26) [12]прочитал в справке, что в описании интерфейса не может быть переменных, только процедуры и функции. А как же быть с обработчиками событий?
← →
Чапаев © (2005-12-09 20:18) [13]
> не может быть переменных, только процедуры и функции
Неверно. Ещё могут быть свойства.
← →
jack128 © (2005-12-09 20:45) [14]FH (09.12.05 19:26) [12]
А как же быть с обработчиками событий?
а что обработчики событий?? Это же просто методы. А в чем проблема??
← →
FH (2005-12-10 14:52) [15]Ну, я пишу ему:
ItttConnection = interface(IUnknown)
OnRead : TConnectionReadEvent;
procedure Run;
procedure Stop;
procedure SendString(s : string);
end;
А он мне:
Field declarations not allowed in interface type
← →
jack128 © (2005-12-10 16:13) [16]ну во первых, это не обработчик события, а поле. а во вторых те нужно сделать примерно так:
ItttConnection = interface(IUnknown)
{ Getters&Setters }
function GetOnRead: TConnectionReadEvent;
procedure SetOnRead(const Value: TConnectionReadEvent);
property OnRead : TConnectionReadEvent read GetOnRead write SetOnRead;
procedure Run;
procedure Stop;
procedure SendString(s : string);
end;
а уже в классах, реализующих этот интерфейс объявлять поле..
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2006.06.25;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c