[Lazarus] TSynEdit bug in destructor?
Bart
bartjunk64 at gmail.com
Tue Nov 8 17:49:48 CET 2011
On 11/8/11, Mattias Gaertner <nc-gaertnma at netcologne.de> wrote:
> You should not free components while they process events.
> Use instead:
> Application.ReleaseComponent(Ed);
> This will free the component after the event.
>
I tried the following:
The PageControl which has/owns the TabSheet (which owns the SynEdit)
has a function
AddPage which creates the TabSheet and SynEdit on it, basically like this:
function TEditorPageControl.AddPage: TEditor;
var
TS: TTabSheet;
E: TEditor;
PgIdx: Integer;
begin
Result := nil;
TS := TTabSheet.Create(Self);
TS.PageControl := Self;
PgIdx := TS.PageIndex;
E := TEditor.Create(TS); //<- TEditor is TSynEdit derived
ActivePage := Pages[PgIdx];
end;
The function ClosePage which removes the TabSheet and SynEdit on it
basically does:
function TEditorPageControl.ClosePage(Index: Integer): Boolean;
var
Cancel: Boolean;
Pg: TTabSheet;
begin
Result := False;
if (Index > PageCount - 1) then Exit;
Pg := Pages[Index]; //<-- Pg owns the SynEdit
Cancel := False;
if Assigned(FOnBeforeCloseEditor) then FOnBeforeCloseEditor(Pg, Cancel);
if Not Cancel then
begin
Pg.PageControl := nil;
Pg.Free;
Result := True;
if PageCount = 0 then InternalEditorStatusChange(nil, scAll);
end;
end;
I then changed this into:
function TEditorPageControl.ClosePage(Index: Integer): Boolean;
var
Cancel: Boolean;
Pg: TTabSheet;
Ed: TEditor;
begin
Result := False;
if (Index > PageCount - 1) then Exit;
Pg := Pages[Index]; //<-- Pg owns the SynEdit
Cancel := False;
if Assigned(FOnBeforeCloseEditor) then FOnBeforeCloseEditor(Pg, Cancel);
if Not Cancel then
begin
//newly added code
Ed := EditorAtPage(Pg); //<- returns the SynEdit in question
Application.ReleaseComponent(Ed);
Application.ProcessMessages;
//end newly added code
Pg.PageControl := nil;
Pg.Free;
Result := True;
if PageCount = 0 then InternalEditorStatusChange(nil, scAll);
end;
Debugln('TEditorPageControl.ClosePage End.');
end;
This did not work, so I changed it into
function TEditorPageControl.ClosePage(Index: Integer): Boolean;
var
Cancel: Boolean;
Pg: TTabSheet;
Ed: TEditor;
begin
Result := False;
if (Index > PageCount - 1) then Exit;
Pg := Pages[Index]; //<-- Pg owns the SynEdit
Cancel := False;
if Assigned(FOnBeforeCloseEditor) then FOnBeforeCloseEditor(Pg, Cancel);
if Not Cancel then
begin
Ed := EditorAtPage(Pg); //<- returns the SynEdit in question
Application.ReleaseComponent(Ed);
Application.ProcessMessages;
Pg.PageControl := nil;
Application.ReleaseComponent(Pg);
Application.ProcessMessages;
Result := True;
if PageCount = 0 then InternalEditorStatusChange(nil, scAll);
end;
end;
I had to use Application.ReleaseComponent on both the SynEdit and the
TabSheet in order to get it to work.
Does this look OK?
>> Feauture or bug?
> By design. You should not free something that is in use.
That depends on the meaning of "in use" ;-)
I did not know it (the SynEdit) was actually doing something at all.
This code worked perfectly in Delphi 3.
It also works fine if the SynEdit is replaced by a Memo.
Thanks for the help.
Bart
More information about the Lazarus
mailing list