Hmmm. Well, I knocked together a sample form to test things:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls;
type
TMyComponent = class(TComponent)
protected
procedure Notification(AComponent: TComponent; Operation:
TOperation); override;
end;
TMyComponent2 = class(TComponent)
protected
constructor CreateMe(POwner: TComponent; PNotifyComponent:
TComponent);
end;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
MyComponent: TMyComponent;
MyComponent2: TMyComponent2;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TMyComponent.Notification(AComponent: TComponent; Operation:
TOperation);
begin
inherited;
if (AComponent is TMyComponent2) and (Operation = opRemove) then
begin
ShowMessage('Can''t say I wasn''t told...');
end;
end;
constructor TMyComponent2.CreateMe(POwner: TComponent; PNotifyComponent:
TComponent);
begin
inherited Create(POwner);
FreeNotification(PNotifyComponent);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyComponent := TMyComponent.Create(Self);
MyComponent2 := TMyComponent2.CreateMe(Self, MyComponent);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MyComponent2.Free;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
MyComponent.Free;
end;
end.
and if I click the buttons in order, my component receives OpRemove
notification when I click button 2, as expected. And they're non-visual
components, so no problem there. And both component have the same owner
- I tried it with nil as an owner and it still worked. That's using
FreeNotification.
>Can't use FreeNotification as it checks who the owner of the two
components are and if they are the same it does not add it to the
>FreeNotifies list. Tried that one already.
Well, it seemed to. Did I miss something?
Cheers,
Carl Reynolds Ph: +64-9-4154790
CJN Technologies Ltd. Fax: +64-9-4154791
[EMAIL PROTECTED] DDI: +64-9-4154795
PO Box 302-278, North Harbour, Auckland, New Zealand
12 Piermark Drive, North Harbour Estate, Auckland, NZ
Visit our website at http://www.cjntech.co.nz/
> -----Original Message-----
> From: [EMAIL PROTECTED] [SMTP:[EMAIL PROTECTED]]
> Sent: Tuesday, July 06, 1999 3:14 PM
> To: '[EMAIL PROTECTED]'
> Subject: RE: [DUG]: Notification Bug on Remove???
>
> That's the whole POINT it DOES NOT WORK. Have now spent several hours
> tracing through the source code using the Debugger to check what was
> occurring - I did not believe this was the problem initially.
>
> I only found it during testing of Creation Order of Components and
> having Contructors throw exceptions during Form creation to test the
> components destructors cleanup code (which failed of course) as no
> Notification( , OpRemove) was received as the Non-Visual components
> were destroyed.
>
> I was VERY surprised to find the OpRemove notifications not working
> for Non-Visual components eg TDatabase, TQuery etc - Any TControl or
> TWinControl does not have this problem, as they get destroyed in
> TWinControl.Destory, and hence do not have this problem,
>
> Can't use FreeNotification as it checks who the owner of the two
> components are and if they are the same it does not add it to the
> FreeNotifies list. Tried that one already.
>
> Seems like the only solution is to change TComponent.DestroyComponents
> to call RemoveComponent instead of Remove.
> Myles.
>
>
> -----Original Message-----
> From: Carl Reynolds [SMTP:[EMAIL PROTECTED]]
> Sent: Tuesday, July 06, 1999 2:36 PM
> To: Multiple recipients of list delphi
> Subject: RE: [DUG]: Notification Bug on Remove???
>
> If you want a component (TMyComponent) to be notified about another
> component being freed, eg. when one of its sub-components
> (TMySubComponent) is removed, call
> TMySubComponent.FreeNotification(TMyComponent) at some point, usually
> during TMySubComponent's construction. Then TMyComponent gets an
> OpRemove notification just before TMySubComponent is freed. That's
> without using InsertComponent or RemoveComponent - is that what you
> meant?
>
> If you want to let other components on a form know of a component's
> impending demise, and those other components haven't been given
> FreeNotification from the component, then the form has to do the work
> (iterating through its components list to let the appropriate
> components know as required). Hope that helps...
>
> Cheers,
>
> Carl Reynolds Ph: +64-9-4154790
> CJN Technologies Ltd. Fax: +64-9-4154791
> [EMAIL PROTECTED] DDI: +64-9-4154795
> PO Box 302-278, North Harbour, Auckland, New Zealand
> 12 Piermark Drive, North Harbour Estate, Auckland, NZ
> Visit our website at http://www.cjntech.co.nz/
>
> -----Original Message-----
> From: Myles Penlington [SMTP:[EMAIL PROTECTED]]
> Sent: Tuesday, July 06, 1999 11:53 AM
> To: Multiple recipients of list delphi
> Subject: [DUG]: Notification Bug on Remove???
>
> What's your understanding of the Delphi Notification mechanism??
>
> My understanding is that if a TComponent or its descendant is removed
> from a Form then all other components on the Form will be sent a
> Notification ( MyComponent, OpRemove) - of course its owner is the
> form - this all stuff in the DFM.
>
> However this appears to be NOT the case. No OpRemove notification sent
> is if the component being removed is descended from TComponent eg
> TQuery etc - It does work if you remove a TControl or TWinControl.
>
> e.g. If you put a TButton , TDatabase and a TQuery on a form (in that
> order), the TDatabase does not get notified of the destruction of the
> TQuery - not that it matters in this case (but we have other cases
> that do matter - our own components).
>
> The offending code is in TComponent.
>
> procedure TComponent.DestroyComponents; // This is called from
> TComponent.Destroy
> var
> Instance: TComponent;
> begin
> while FComponents <> nil do
> begin
> Instance := FComponents.Last;
> Remove(Instance); // IF THIS WAS RemoveComponent then all would be
> okay, or if TComponent.Remove did not set the owner to NIL.
> Instance.Destroy;
> end;
> end;
>
> Do I have my understanding wrong or is this a serious bug/stuff up??
> Can someone (Richard/Nic?) explain why it has been done this way??
> By the way all the components do get a Notification( , OpInsert), when
> they are created from the DFM, they just do not get the OpRemove when
> the form is destroyed, this occurs as TComponent.Create does a
> InsertComponent which does do a notification.
>
> Comments Please.
>
> Regards
>
> Myles Penlington
> ADVANCED MANAGEMENT SYSTEMS
>
> ----------------------------------------------------------------------
> -----
> New Zealand Delphi Users group - Delphi List -
> [EMAIL PROTECTED]
> Website: http://www.delphi.org.nz
application/ms-tnef