Вот токое дело — сделал компонент у которого имеется один Property токого же
типа как он сам. Тоесть
ложиш на форму два компонента и у делаеш что первии указывает на другого.
Ну типо как кладёш один dataset и 4 datasources, и всем datasource-м
указываеш один dataset.
Вот немогу понять как в коде самого компонента можно реализовать токое, чтоб
я из етого главного мог наити ети все которие указывает на его ...
Как ето сделать ???
Best regards
Janex
Posted via RSDN NNTP Server 1.8 beta
Re: Как наити связаные компоненти ???
От:
Аноним
Дата:
04.12.03 08:54
Оценка:
Здравствуйте, Janex, Вы писали:
J>Вот токое дело — сделал компонент у которого имеется один Property токого же J>типа как он сам. Тоесть J>ложиш на форму два компонента и у делаеш что первии указывает на другого. J>Ну типо как кладёш один dataset и 4 datasources, и всем datasource-м J>указываеш один dataset. J>Вот немогу понять как в коде самого компонента можно реализовать токое, чтоб J>я из етого главного мог наити ети все которие указывает на его ... J>Как ето сделать ???
Например кусок обработчика формы. А саму форму можно получить через свойство Parent или лучше Owner.
for I := 0 to (ComponentCount - 1) do
begin
if (Component[I] is TMyComponent) then
begin//end;
end;
Здравствуйте, Janex, Вы писали: J>Вот немогу понять как в коде самого компонента можно реализовать токое, чтоб J>я из етого главного мог наити ети все которие указывает на его ... J>Как ето сделать ???
1. Искать все компоненты, лежащие на форме:
if Assigned(Owner)
then do begin
for i:= 0 to Owner.ComponentCount-1 do
begin
if Owner.Components[i] is TMyComponent
then begin
if TMyComponent(Owner.Components[i]).ReferenceProperty = self
then begin// Ну вот мы и нашли компонент, который ссылается на нас.end;
end;
end;
end;
Плохо. На нас могут ссылаться и из других форм.
2. Регистрировать ссылки.
TMyComponent = class
private
procedure SetReferenceProperty(Value: TMyComponent);
FReferenceProperty: TMyComponent;
FReferencesList: TList;
RemoveReference(Ref: TMyComponent);
AddReference(Ref: TMyComponent);
published
ReferenceProperty: TMyComponent read FReferenceProperty write SetReferenceProperty;
end;
implementation
procedure TMyComponent.SetReferenceProperty(Value: TMyComponent);
begin
if Value = FReferenceProperty then exit;
if Assigned(FReferenceProperty)
then FReferencePropery.RemoveReference(self);
if Assigned(Value)
then Value.AddReference(self);
FReferenceProperty := Value;
end;
Подразумевается, что AddReference/RemoveReference вносят соответствующие изменения в FReferencesList. Тогда в любой момент можно получить список всех ссыляющихся, глянув в свой FReferencesList.
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Hello, !
You wrote on Thu, 04 Dec 2003 08:54:44 GMT:
> Здравствуйте, Janex, Вы писали:
J>> Вот токое дело — сделал компонент у которого имеется один Property J>> токого же типа как он сам. Тоесть ложиш на форму два компонента и у J>> делаеш что первии указывает на другого. J>> Ну типо как кладёш один dataset и 4 datasources, и всем datasource-м J>> указываеш один dataset. J>> Вот немогу понять как в коде самого компонента можно реализовать J>> токое, чтоб я из етого главного мог наити ети все которие указывает J>> на его ... J>> Как ето сделать ???
> Например кусок обработчика формы. А саму форму можно получить через > свойство Parent или лучше Owner.
>
> for I := 0 to (ComponentCount - 1) do begin if (Component[I] is
> TMyComponent) then begin//
> end;
> end;
>
Так, возможно, не пойдет, т.к. автор не сказал как будут использоваться компоненты(а если верить Рею Конопке, то ни один автор компонентов не может этого предположить %) ):
1. Owner = nil и/или Parent = nil;
2. Компоненты на разных формах.
Как вариант сделать у компонента скрытое свойство — "прилинкованные объекты" типа TList и при создании линка добавлять ссылку в этот список (ведь класс-то один, а значит есть доступ к private полям), соответственно при смене линка или разрушении объекта — удалять
Возможно для этого придется создать предка какого нибудь с виртуальными методами AddLink(AMyComponent : TMyComponent) и RemoveLink(AMyComponent : TMyComponent) если все не заработает так.
А еще лучше посмотреть реализацию TDataSource, ведь он же вычисляет как-то наличие DataSet %).
PS Автору топика: научись, пожалуйста, пользоваться спелчекером, а то читать трудно.
Вообше то я не совсем гуру в сосдание компонентов, но етот код както
непроходит ... ((
Типо идея наверно правильное, но догадываюсь, что написано
ето на ходу и "неправерено електроникои" ...
Hello, Janex!
You wrote on Thu, 04 Dec 2003 13:49:35 GMT:
J> Вообше то я не совсем гуру в сосдание компонентов, но етот код както J> непроходит ... (( J> Типо идея наверно правильное, но догадываюсь, что написано ето на J> ходу и "неправерено електроникои" ...
J> P.S. J> Имеется ввиду код с Tlist — ом ..
Его можно попробовать создать в конструкторе
И опиши ошибки подробнее или рабочий код компонента пришли (выкинув то, что не касается темы), чтоб запустили, да отладили...
>> И опиши ошибки подробнее или рабочий код компонента пришли (выкинув то,
что не касается темы), чтоб запустили, да >> отладили...
>> With best regards, Alexander Diouzshev-Maltsev.
Привет.
Компонент та маленькии и простенькии. Всё вроде как прекрасно работает кроме
описанои
эфичи которую както неудаётся прикрутиь ... ((
Идея компонента токова: Кидаеш оди главнии на главную форму и пишиш какоито
код в евенте OnTunelEvent.
Далее в остальных формах, в том числе в формар которие в dll живут кидем те
же компоненти и
указываем им MasterTunel ...
Шас из любои форми можем без лишнего кода или wиндоwских messages посилать
чтото главнои
комоненте — вроде как удобно ...
Но оч хочется чтоб главнии компонент мог посылать чтото всем к другим
компонентам которие
в MasterTunel указывает на него ...
Как послать им чтото наверна и сам бы разобрался бы, но неумею да них
дастучатся ....(((
Код примерно такои (шас нерабочии изза дабавленои неработюшеи фичи ) :
unit MDTunelMsg;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls;
Type
TTunelEvent = procedure(tnlMessage :String; tnlParam :Variant;
tnlMessageID :Integer) Of Object;
Type
TMDTunelMsg = class(TComponent)
private
FMasterTunel :TMDTunelMsg;
FOnTunelEvent :TTunelEvent;
FReferenceProperty: TMDTunelMsg;
FReferencesList: TList;
RemoveReference(Ref: TMDTunelMsg);
AddReference(Ref: TMDTunelMsg);
procedure SetReferenceProperty(Value: TMDTunelMsg);
protected
public
Constructor Create(AOwner: TComponent); override;
procedure SendToMaster(tnlMessage :String; tnlParam :Variant;
tnlMessageID :Integer);
published
Property ReferenceProperty: TMDTunelMsg read FReferenceProperty write
SetReferenceProperty;
Property MasterTunel :TMDTunelMsg Read FMasterTunel Write FMasterTunel;
property OnTunelEvent :TTunelEvent Read FOnTunelEvent Write
FOnTunelEvent;
end;
implementation
constructor TMDTunelMsg.Create(AOwner: TComponent);
begin// FReferencesList := TList.Create;inherited;
end;
procedure TMDTunelMsg.SetReferenceProperty(Value: TMDTunelMsg);
begin
if Value = FReferenceProperty then exit;
if Assigned(FReferenceProperty)
then FReferencePropery.RemoveReference(self);
if Assigned(Value)
then Value.AddReference(self);
FReferenceProperty := Value;
end;
procedure TMDTunelMsg.SendToMaster(tnlMessage :String; tnlParam :Variant;
tnlMessageID :Integer);
begin
MasterTunel.OnTunelEvent(tnlMessage, tnlParam, tnlMessageID);
end;
end.
Ну а кто будет за тебя реализовывать методы
RemoveReference(Ref: TMDTunelMsg);
AddReference(Ref: TMDTunelMsg);
??? Реализуй их, и код сразу же станет рабочим.
P/s/ не рассчитывай, что хдесь за тебя все напишут. Придется и думать немножко самому, и код самому писать.
з.з.ы. Раскомментарь строчку в конструкторе. и деструктор тоже надо оверрайдить и в нем список Free, а то утечки памяти будут.
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
>> Ну а кто будет за тебя реализовывать методы >> RemoveReference(Ref: TMDTunelMsg); >> AddReference(Ref: TMDTunelMsg); >> ??? Реализуй их, и код сразу же станет рабочим. >> P/s/ не рассчитывай, что хдесь за тебя все напишут. Придется и думать
немножко самому, и код самому писать. >з.з.ы. Раскомментарь строчку в конструкторе. и деструктор тоже надо
оверрайдить и в нем список Free, а то утечки памяти >>будут.
Да нерасшитовал кто ктото всё напишет за меня, но всётаки
что и как писать для :
AddReference(Ref: TMDTunelMsg);
RemoveReference(Ref: TMDTunelMsg);
??? ((
Подразумевается, что AddReference/RemoveReference вносят соответствующие изменения в FReferencesList.
J>что и как писать для : J> AddReference(Ref: TMDTunelMsg);
Здесь надо добавить в FReferencesList переданный аргумент J> RemoveReference(Ref: TMDTunelMsg);
А здесь его надо убрать из FReferencesList.
Как именно — попробуй почитать хоть немножко help по TList.
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Hello, Janex!
You wrote on Fri, 05 Dec 2003 12:28:49 GMT:
>>> И опиши ошибки подробнее или рабочий код компонента пришли (выкинув >>> то, J> что не касается темы), чтоб запустили, да >>> отладили...
>>> With best regards, Alexander Diouzshev-Maltsev.
J> Привет. J> Компонент та маленькии и простенькии. Всё вроде как прекрасно J> работает кроме описанои эфичи которую както неудаётся прикрутиь ... J> (( J> Идея компонента токова: Кидаеш оди главнии на главную форму и пишиш J> какоито код в евенте OnTunelEvent. J> Далее в остальных формах, в том числе в формар которие в dll живут J> кидем те же компоненти и указываем им MasterTunel ... J> Шас из любои форми можем без лишнего кода или wиндоwских messages J> посилать чтото главнои комоненте — вроде как удобно ... J> Но оч хочется чтоб главнии компонент мог посылать чтото всем к другим J> компонентам которие в MasterTunel указывает на него ... J> Как послать им чтото наверна и сам бы разобрался бы, но неумею да них J> дастучатся ....(((
Насчет dll ничего сказать не могу %( скорее всего работать не будет...
Вот функции, которых так не хватало... + проверки всякие по вкусу...
procedure TMDTunelMsg.AddReference(Ref: TMDTunelMsg);
begin
if Assigned(Ref) and (FReferencesList.IndexOf(Ref) >= 0) then
FReferencesList.Add(Ref);
end;
destructor TMDTunelMsg.Destroy;
var
i : integer;
begin
for i := 0 to FReferencesList.Count - 1 do
if Assigned(FReferencesList.Items[i]) then
TMDTunelMsg(FReferencesList.Items[i]).ReferenceProperty := nil;
FReferencesList.Free;
inherited;
end;
procedure TMDTunelMsg.RemoveReference(Ref: TMDTunelMsg);
begin
if Assigned(Ref) then
FReferencesList.Remove(Ref);
end;
Здравствуйте, Diouzshev, Вы писали: D>Вот функции, которых так не хватало... + проверки всякие по вкусу...
мелкое исправление:
procedure TMDTunelMsg.AddReference(Ref: TMDTunelMsg);
begin
if Assigned(Ref) and (FReferencesList.IndexOf(Ref) = -1) then
FReferencesList.Add(Ref);
end;
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Hello, Sinclair!
You wrote on Mon, 08 Dec 2003 09:12:25 GMT:
S> мелкое исправление:
S>
S> procedure TMDTunelMsg.AddReference(Ref: TMDTunelMsg);
S> begin
S> if Assigned(Ref) and (FReferencesList.IndexOf(Ref) = -1) then
S> FReferencesList.Add(Ref);
S> end;
S>
Не такое уж и мелокое =), конечно же так, ошибся...
Hello, Diouzshev!
You wrote on Mon, 08 Dec 2003 08:37:26 GMT:
D> destructor TMDTunelMsg.Destroy; D> var i : integer; D> begin for i := 0 to FReferencesList.Count — 1 do if D> Assigned(FReferencesList.Items[i]) then D> TMDTunelMsg(FReferencesList.Items[i]).ReferenceProperty := nil; D> FReferencesList.Free;
D> inherited; D> end;
и это неправильно (( т.к. TMDTunelMsg(FReferencesList.Items[i]).ReferenceProperty := nil удаляет элемент списка.
Лучше так:
destructor TMDTunelMsg.Destroy;
var i : integer;
begin
while FReferencesList.Count > 0 do
if Assigned(FReferencesList.Items[0]) then
TMDTunelMsg(FReferencesList.Items[0]).ReferenceProperty := nil
else
FReferencesList.Delete(0);
FReferencesList.Free;
inherited;
end;