Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 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.49 MB
Время: 0.009 c
2-1149751434
XTD
2006-06-08 11:23
2006.06.25
Глючит MediaPleyer


8-1137672445
VasRoG
2006-01-19 15:07
2006.06.25
Pixel Format


2-1149582297
evgenij_
2006-06-06 12:24
2006.06.25
Menu


1-1147777263
Stanislav
2006-05-16 15:01
2006.06.25
Данные в WORD из Потока


15-1148657025
AlexanderMS
2006-05-26 19:23
2006.06.25
Кругом шпионы?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский