LCL: fixed TApplication.ReleaseComponent when components in list are freed by other means

git-svn-id: trunk@22905 -
This commit is contained in:
mattias 2009-12-01 17:36:53 +00:00
parent 05fc992191
commit 53ede9fe10
3 changed files with 38 additions and 33 deletions

View File

@ -85,6 +85,8 @@ type
constructor Create(TheOwner: TComponent); override;
end;
{ TEasyDockBook }
TEasyDockBook = class(TForm)
pnlDock: TPanel;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
@ -155,6 +157,7 @@ begin
{$ELSE}
//not required?
{$ENDIF}
DebugLn(['TEasyDockBook.FormClose ',DbgSName(Self),' ',dbgs(Pointer(Self))]);
CloseAction := caFree;
end;
@ -226,7 +229,7 @@ begin
Client.Visible := True; //make hidden page control visible
end;
Tabs.ButtonList.Delete(i);
btn.Free; //seems to work
Application.ReleaseComponent(btn);
//special handle remove of current and last tab
{$IFDEF new}
//if not StayDocked and (Tabs.ButtonCount = 1) then begin
@ -241,7 +244,7 @@ begin
{$ELSE}
CurTab.Control.ManualDock(HostDockSite, self, alLeft);
{$ENDIF}
PostMessage(Self.Handle, WM_CLOSE, 0, 0);
Release;
end else begin
end;
end else
@ -267,12 +270,7 @@ begin
//DoUnDock(nil, nil);
//Dock(nil);
end;
//Release; //Close;
{$IFDEF WIN32}
PostMessage(Self.Handle, WM_CLOSE, 0, 0);
{$ELSE}
//how to close from within an event handler?
{$ENDIF}
Release;
end;
//update the host dock site and its DockManager
if HostDockSite <> nil then begin

View File

@ -1100,6 +1100,7 @@ type
FApplicationType: TApplicationType;
FCaptureExceptions: boolean;
FComponentsToRelease: TAvgLvlTree;
FComponentsReleasing: TAvgLvlTree;
FCreatingForm: TForm;// currently created form (CreateForm), candidate for MainForm
FFindGlobalComponentEnabled: boolean;
FFlags: TApplicationFlags;

View File

@ -239,6 +239,8 @@ begin
FHintTimer:=nil;
if FComponentsToRelease<>nil then
FComponentsToRelease.Remove(AComponent);
if FComponentsReleasing<>nil then
FComponentsReleasing.Remove(AComponent);
if AComponent = MainForm then begin
FMainForm:= nil;
Terminate;
@ -2043,43 +2045,47 @@ end;
procedure TApplication.ReleaseComponents;
var
List: TFPList;
Node: TAvgLvlTreeNode;
Component: TComponent;
i: Integer;
Node: TAvgLvlTreeNode;
begin
if FComponentsToRelease<>nil then begin
if FComponentsReleasing<>nil then exit; // currently releasing
if (FComponentsToRelease<>nil) then begin
if FComponentsToRelease.Count=0 then begin
FreeAndNil(FComponentsToRelease);
exit;
end;
// free components
// Notes:
// - check TLCLComponent.LCLRefCount=0
// - during freeing new components can be added to the FComponentsToRelease
List:=nil;
// - components can be removed from FComponentsToRelease and FComponentsReleasing
FComponentsReleasing:=FComponentsToRelease;
FComponentsToRelease:=nil;
try
// collect all components that can be freed
Node:=FComponentsToRelease.FindLowest;
while Node<>nil do begin
while (FComponentsReleasing<>nil) and (FComponentsReleasing.Count>0) do
begin
Node:=FComponentsReleasing.FindLowest;
Component:=TComponent(Node.Data);
if (not (Component is TLCLComponent))
or (TLCLComponent(Component).LCLRefCount=0) then begin
if List=nil then
List:=TFPList.Create;
List.Add(Component);
end;
Node:=FComponentsToRelease.FindSuccessor(Node);
end;
// free components
if List<>nil then
for i:=0 to List.Count-1 do begin
Component:=TComponent(List[i]);
FComponentsToRelease.Remove(Component);
//DebugLn(['TApplication.ReleaseComponents ',DbgSName(Component)]);
FComponentsReleasing.Delete(Node);
if (Component is TLCLComponent)
and (TLCLComponent(Component).LCLRefCount>0) then begin
// add again to FComponentsToRelease
ReleaseComponent(Component);
end else begin
Component.Free;
end;
end;
finally
List.Free;
// add remaining to FComponentsToRelease
while (FComponentsReleasing<>nil) and (FComponentsReleasing.Count>0) do
begin
Node:=FComponentsReleasing.FindLowest;
Component:=TComponent(Node.Data);
FComponentsReleasing.Delete(Node);
ReleaseComponent(Component);
end;
FreeAndNil(FComponentsReleasing);
end;
if FComponentsToRelease.Count=0 then
FreeAndNil(FComponentsToRelease);
end;
end;