I found a strange issue with a custom component that creates/destroys subcomponents dynamically.
type
TPanelTest = class(TPanel)
private
FShowPanel : Boolean;
FPanel : TPanel;
function GetShowPanel: Boolean;
procedure SetShowPanel(const Value: Boolean);
procedure CreateSubPanel;
procedure DestroySubPanel;
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property ShowPanel : Boolean read GetShowPanel write SetShowPanel;
end;
...
{ TPanelTest }
constructor TPanelTest.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
SetBounds(0, 0, 300, 300);
ShowPanel := True;
end;
procedure TPanelTest.CreateSubPanel;
begin
if not Assigned(FPanel) then
begin
FPanel := TPanel.Create(Self);
with FPanel do
begin
SetSubComponent(True);
Parent := Self;
Caption := '';
Top := 0;
Left := 0;
Height := 50;
Align := alTop;
end;
end;
end;
procedure TPanelTest.DestroySubPanel;
begin
if Assigned(FPanel) then
FreeAndNil(FPanel);
end;
function TPanelTest.GetShowPanel: Boolean;
begin
Result := FShowPanel;
end;
procedure TPanelTest.SetShowPanel(const Value: Boolean);
begin
FShowPanel := Value;
if Value then
CreateSubPanel
else
DestroySubPanel;
end;
In run-time and design-time, everything (creating and destroying FPanel) works correct, but if I set ShowPanel to False, then save the project, close and open it again, I get an error:
Error creating form: Access violation at address 50CF4B9C in module 'vcl270.bpl'. Read of address 00000000.
If I manually change ShowPanel to True in the .dfm file, everything starts work correct again.
So, what am I missing? I'm using Delphi 10.4.2 CE
For now, I use a workaround with making SubPanel invisible instead of destroying it, but I want to make this right.
SetShowPaneltries to runDestroySubPanel; but FPanel was never created and so (iiuic), accessingFPanelchokes. Been some time since I've touched Delphi...FPanelwhen settingShowPanelto True in constructor. On second step Delphi set properties from dfm and after that I get error. But I can't catch where error appears. And as I said when I play with settingShowPanelto false and back to true runtime and design time (from object inspector) - everything is ok.ShowPanel=Truein the constructor, you should adddefault Trueto the declaration of theShowPanelproperty, eg:property ShowPanel : Boolean read GetShowPanel write SetShowPanel default True;Otherwise the DFM will think the default is False instead. Also, you don't need to checkAssigned()before callingFreeAndNil(), it already handles that internally. Also, when you have design-time errors like this, you can run a 2nd instance of the IDE to debug the 1st instance so you can step through your code at design-time.