Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Создание компонента [D6, Win2k]


vladmk ©   (2005-12-01 10:16:00) 

Суть вопроса в следующем:
Имеется несколько компонентов(Компон1, Компон2 .. КомпонN) которые имеют общего предка и у них одинаковые названия у public и published методов и свойств, но разная их реализация.
Вопрос: как создать компонент к которому в design-time и run-time можно  подключать один из компонентов (Компон1, Компон2 .. КомпонN) и работать с их методами и свойствами.
Заранее благодарен всем ответившим.


jack128   (2005-12-10 16:13:00) [1]

ну во первых, это не обработчик события, а поле. а во вторых те нужно сделать примерно так:

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;

а уже в классах, реализующих этот интерфейс объявлять поле..


FH   (2005-12-10 14:52:00) [2]

Ну, я пишу ему:

 ItttConnection = interface(IUnknown)
   OnRead : TConnectionReadEvent;
   procedure Run;
   procedure Stop;
   procedure SendString(s : string);
 end;

А он мне:
Field declarations not allowed in interface type


jack128   (2005-12-09 20:45:00) [3]

FH   (09.12.05 19:26) [12]
А как же быть с обработчиками событий?

а что обработчики событий?? Это же просто методы.  А в чем проблема??


Чапаев   (2005-12-09 20:18:00) [4]


> не может быть переменных, только процедуры и функции

Неверно. Ещё могут быть свойства.


FH   (2005-12-09 19:26:00) [5]

прочитал в справке, что в описании интерфейса не может быть переменных, только процедуры и функции. А как же быть с обработчиками событий?


jack128   (2005-12-03 19:41:00) [6]

Например в этом коде, если ты уничтожишь сначала MyIdIdServerVar, а потом SomeComp, то в  SomeComp.Destroy получишь AV. Чтобы его избежать, нужно перед уничтожением MyIdIdServerVar обнилить свойство MyServer.


FH   (2005-12-03 17:28:00) [7]

спасибо
А что там насчет глюков?
Это должно работать?


jack128   (2005-12-03 17:19:00) [8]

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 16:48:00) [9]

Это примерно понятно, у меня они все будут наследниками TComponent, с IUnknown заморачиваться не буду.
Сперва описываю интерфейс IMyServer, у него будет несколько процедур и событий. Потом переписываю мой первый компонент, как class(TIdUDPServer, IMyServer), у него все методы должны совпадать с тем, ч то я написал в IMyServer. А дальше? Компонент, в котором я смогу в runtime поменять TMyIdUDPServer на TMyIdIdServer?


jack128   (2005-12-03 16:35:00) [10]

Ну например:
Интерфейс
 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:00) [11]

Сорри, опечатка
ISchemeItemControl = interface(IUnknown)
['{73861986-6815-46F1-8CBF-538AC822C42E}']
  function GetSchemeItem: TSchemeItem;
  property SchemeItem: TSchemeItem read GetSchemeItem;
end;


FH   (2005-12-03 16:11:00) [12]

и как реализовать его во всех 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...


FH   (2005-12-03 15:45:00) [13]

Спасибо, а как объявить интерфейс?


jack128   (2005-12-03 14:56:00) [14]

FH   (03.12.05 13:17) [2]
А если у них нет общего предка,

Объявить интерфейс, реализовать его  во всех Comp1..CompN, а твоем новом компоненте описать published свойство интерфейсного типа..


FH   (2005-12-03 13:17:00) [15]

А если у них нет общего предка, только одинаковые методы и свойства?


Юрий Зотов   (2005-12-01 23:08:00) [16]

Если компоненты 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;


Наверх

Титульная страница Поиск, карта сайта Написать письмо