Mega Code Archive

 
Categories / Delphi / VCL
 

Add Multiowner Support to TComponent

Title: add Multiowner Support to TComponent Question: How To Add Multiowner Support to TComponent Answer: Add Multiowner Support to your Components You maybe ask yourself what is the benefits from multiowner support ? First I will till you what is sort of code that you maybe need to add multiowner support to. Suppose that you have TDataSet object that hold sort of data that is needed to represented to the user using several Views ( Forms ) Like Tree view (TTreeView) and Grid (TGridView) and Chart View (TChartView) . ets Where all of this views share the same TDataSet object as source of data at the same time I don't want to make any memory leaks in my code .. that mean I wan't to free TDataSet object from memory when the user finishe from all views ( I mean when he close all forms connected to the same data object ) So what is the appropriate time to free TDataSet Object from memory ? Of Course the answer is when all Views are gone So how could I know the time when the user close all the Views ?? (Another problem!!!) TDestoryNofitier will Solve this problem (of course TDestoryNofitier will remove itself from memory too) procedure ShowViews(Data:TDataSet); var v1,v2,v3,v4:TForm; DstNtf:TDestroyNotifier; begin v1:=TGridView.Create(nil); TGridView(v1).Data:=Data; v1.Show; v2:=TTreeView.Create(nil); TTreeView(v2).Data:=Data; v2.Show; v3:=TChartView.Create(nil); TChartView(v3).Data:=Data; v3.Show; DstNtf:=TDestroyNotifier.Create; DstNtf.AddOwnerComponent(v1); DstNtf.AddOwnerComponent(v2); DstNtf.AddOwnerComponent(v3); DstNtf.AddOwnedComponent(Data); end; unit DestroyNotifier; interface uses SysUtils,Classes,Contnrs,Forms; type TDestroyNotifier=class(TComponent) private FOwned:TObjectList; FOwners:TObjectList; protected procedure Notification(AComponent: TComponent; Operation: TOperation);override; public constructor Create;reintroduce; destructor Destroy; override; procedure AddOwnerComponent(AOwner:TComponent); procedure AddOwnedComponent(AOwned:TComponent); end; implementation { TDestroyNotifier } procedure TDestroyNotifier.AddOwnedComponent(AOwned: TComponent); begin if FOwned.IndexOf(AOwned)=-1 then begin if AOwned.Ownernil then AOwned.Owner.RemoveComponent(AOwned); AOwned.FreeNotification(Self); FOwned.Add(AOwned); end; end; procedure TDestroyNotifier.AddOwnerComponent(AOwner: TComponent); begin if FOwners.IndexOf(AOwner)=-1 then begin AOwner.FreeNotification(Self); FOwners.Add(AOwner); end; end; constructor TDestroyNotifier.Create; begin FOwned:=TObjectList.Create(false); FOwners:=TObjectList.Create(false); end; destructor TDestroyNotifier.Destroy; begin FOwned.Free; FOwners.Free; inherited; end; procedure TDestroyNotifier.Notification(AComponent: TComponent;Operation: TOperation); var Cmp:TComponent; begin inherited; if csDestroying in Application.ComponentState then Exit; if Operation=opRemove then begin if FOwners.IndexOf(AComponent)-1 then begin FOwners.Extract(AComponent); AComponent.RemoveFreeNotification(Self); if (FOwners.Count begin while FOwned.Count0 do begin Cmp:=TComponent(FOwned[0]); FOwned.Extract(Cmp); Cmp.RemoveFreeNotification(Self); Cmp.Free; end; Free; end; end else if FOwned.IndexOf(AComponent)-1 then begin FOwned.Extract(AComponent); AComponent.RemoveFreeNotification(Self); end; end; end; end.