lcl: properly release control resources on TWinControl.DestroyWnd:

- notify child controls (only TControl, not TWinControl) before parent handle destruction to perform appropriate preparations inside controls
  - release canvas handle of TGraphicControl when before parent handle destruction
(fixes issue #0014152)

git-svn-id: trunk@20874 -
This commit is contained in:
paul 2009-07-17 02:44:31 +00:00
parent 42e7f62664
commit fd9e3c084e
5 changed files with 25 additions and 3 deletions

View File

@ -979,6 +979,7 @@ type
function GetCursor: TCursor; virtual; function GetCursor: TCursor; virtual;
procedure SetCursor(Value: TCursor); virtual; procedure SetCursor(Value: TCursor); virtual;
procedure SetVisible(Value: Boolean); virtual; procedure SetVisible(Value: Boolean); virtual;
procedure DoOnParentHandleDestruction; virtual;
protected protected
// sizing/aligning // sizing/aligning
procedure DoAutoSize; virtual; procedure DoAutoSize; virtual;
@ -1905,6 +1906,8 @@ type
procedure FontChanged(Sender: TObject); override; procedure FontChanged(Sender: TObject); override;
procedure Paint; virtual; procedure Paint; virtual;
procedure DoOnChangeBounds; override; procedure DoOnChangeBounds; override;
procedure DoOnParentHandleDestruction; override;
property OnPaint: TNotifyEvent read FOnPaint write FOnPaint; property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;

View File

@ -3499,6 +3499,11 @@ begin
ControlState := ControlState + [csVisibleSetInLoading]; ControlState := ControlState + [csVisibleSetInLoading];
end; end;
procedure TControl.DoOnParentHandleDestruction;
begin
// nothing, implement in descendats
end;
{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
TControl.SetZOrder TControl.SetZOrder

View File

@ -63,7 +63,7 @@ end;
procedure TCustomControl.DestroyWnd; procedure TCustomControl.DestroyWnd;
begin begin
if FCanvas<>nil then if FCanvas <> nil then
TControlCanvas(FCanvas).FreeHandle; TControlCanvas(FCanvas).FreeHandle;
inherited DestroyWnd; inherited DestroyWnd;
end; end;

View File

@ -104,5 +104,12 @@ begin
TControlCanvas(Canvas).FreeHandle; TControlCanvas(Canvas).FreeHandle;
end; end;
procedure TGraphicControl.DoOnParentHandleDestruction;
begin
inherited;
if Canvas.HandleAllocated then
TControlCanvas(Canvas).FreeHandle;
end;
// included by controls.pp // included by controls.pp

View File

@ -6839,8 +6839,8 @@ begin
if not HandleAllocated then if not HandleAllocated then
RaiseGDBException('TWinControl.FinalizeWnd Handle already destroyed'); RaiseGDBException('TWinControl.FinalizeWnd Handle already destroyed');
// make sure our text is saved // make sure our text is saved
if TWSWinControlClass(WidgetSetClass).GetText(Self, S) if TWSWinControlClass(WidgetSetClass).GetText(Self, S) then
then FCaption := S; FCaption := S;
// if color has changed make sure it will be restored // if color has changed make sure it will be restored
if FColor<>clWindow then if FColor<>clWindow then
Include(FWinControlFlags,wcfColorChanged); Include(FWinControlFlags,wcfColorChanged);
@ -6999,10 +6999,17 @@ end;
Destroys the interface object. Destroys the interface object.
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
procedure TWinControl.DestroyWnd; procedure TWinControl.DestroyWnd;
var
i: integer;
begin begin
if HandleAllocated then if HandleAllocated then
begin begin
FinalizeWnd; FinalizeWnd;
if FControls <> nil then
for i := 0 to FControls.Count - 1 do
TControl(FControls[i]).DoOnParentHandleDestruction;
TWSWinControlClass(WidgetSetClass).DestroyHandle(Self); TWSWinControlClass(WidgetSetClass).DestroyHandle(Self);
Handle := 0; Handle := 0;
// We don't know why we here. Maybe because handle is not needed at moment // We don't know why we here. Maybe because handle is not needed at moment