diff --git a/examples/dockmanager/package/fdockbook.pas b/examples/dockmanager/package/fdockbook.pas index 68eab485a7..768f595453 100644 --- a/examples/dockmanager/package/fdockbook.pas +++ b/examples/dockmanager/package/fdockbook.pas @@ -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 diff --git a/lcl/forms.pp b/lcl/forms.pp index 9e8c15a6cf..f3cc4d3c79 100644 --- a/lcl/forms.pp +++ b/lcl/forms.pp @@ -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; diff --git a/lcl/include/application.inc b/lcl/include/application.inc index 91ed0fc89d..3c0d531c93 100644 --- a/lcl/include/application.inc +++ b/lcl/include/application.inc @@ -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;