I'm facing the Abstract error when i Drag and Dropping a TPanel child in a TImage component.
Basically i have a Scrollbox contain a TPanelCargaRele list and when i drag and drop this panel to the Trash i get the Abstract error.
I've debugged my code, but this problem happens in end; line of the procedure and I couldn't see where the problem is.
Here is my code below:
procedure TFormCenas.imgLixeiraDragDrop(Sender, Source: TObject; X,
Y: Integer);
function getFuncaoCena(p: Pointer): TFuncaoCena;
begin
if Assigned(p) then
begin
if ((TObject(p).ClassType = TPanelCargaRele) or
(TObject(p).ClassType = TPanelCargaDimmer) or
(TObject(p).ClassType = TPanelDefinicaoCargaAV) or
(TObject(p).ClassType = TPanelDefinicaoFuncaoSomfy)) and
(TObject(p).InheritsFrom(TWinControl))
then
begin
if (TObject(p).ClassType = TPanelCargaRele) then
Result := TPanelCargaRele(p).funcaoCena
else if (TObject(p).ClassType = TPanelCargaDimmer) then
Result := TPanelCargaDimmer(p).funcaoCena
else if (TObject(p).ClassType = TPanelDefinicaoCargaAV) then
Result := TPanelDefinicaoCargaAV(p).funcaoCena
else if (TObject(p).ClassType = TPanelDefinicaoFuncaoSomfy) then
Result := TPanelDefinicaoFuncaoSomfy(p).funcaoCena;
end
else if TObject(p).InheritsFrom(TWinControl) then
begin
Result := getFuncaoCena(TWinControl(p).Parent);
end
else
Result := nil;
end
else
Result := nil;
end;
function getObject(p: Pointer): Pointer;
begin
if Assigned(p) then
begin
if ((TObject(p).ClassType = TPanelCargaRele) or
(TObject(p).ClassType = TPanelCargaDimmer) or
(TObject(p).ClassType = TPanelDefinicaoCargaAV) or
(TObject(p).ClassType = TPanelDefinicaoFuncaoSomfy)) and
(TObject(p).InheritsFrom(TWinControl))
then
begin
Result := p;
end
else if TObject(p).InheritsFrom(TWinControl) then
begin
Result := getObject(TWinControl(p).Parent);
end
else
Result := nil;
end
else
Result := nil;
end;
var
funcaoCena: TFuncaoCena;
panel: Pointer;
begin
inherited;
funcaoCena := getFuncaoCena(Source);
if Assigned(funcaoCena) then
begin
listaFuncoesTemp.Remove(funcaoCena);
panel := getObject(Source);
if Assigned(panel) then
begin
TWinControl(panel).Visible := False;
FreeAndNil(TWinControl(panel));
end;
end;
end; //the error happens here..
Here is the constructor of the TPanelCargaRele:
TPanelCargaRele = class(TPanel)
.
.
.
constructor TPanelCargaRele.Create(AOwner: TComponent; aIndice: Integer; item: Pointer);
begin
inherited Create(AOwner);
Parent := TWinControl(AOwner);
//ReleRadio0
fReleRadio := TRadioGroup.Create(Self);
fPanelChecked := TPanel.Create(Self);
fBotaoChecked := TPNGButtonSimple.Create(Self);
fBevelRodape := TBevel.Create(Self);
fEditDelay := TEdit.Create(Self);
//Panel1
Self.Left := 0;
Self.Width := 400;
Self.Height := 40;
Self.Top := aIndice * (Self.Height + 5);
Self.Align := alTop;
Self.BevelInner := bvNone;
Self.BevelOuter := bvNone;
Self.Color := clWhite;
Self.TabOrder := 0;
Self.DragMode := dmAutomatic;
fPanelChecked.Parent := Self;
fPanelChecked.Top := 12;
fPanelChecked.Left := 30;
fPanelChecked.Width := 100;
fPanelChecked.Alignment := taLeftJustify;
fPanelChecked.Height := 13;
fPanelChecked.ParentColor := True;
fPanelChecked.BevelOuter := bvNone;
fPanelChecked.BevelInner := bvNone;
fPanelChecked.Font.Size := 8;
fPanelChecked.DragMode := dmAutomatic;
fPanelChecked.OnDblClick := OnDblClickPanelNome;
// fPanelChecked.OnDblClick := OnDblClickPanelNome;
//
fBotaoChecked.Parent := Self;
fBotaoChecked.Left := 5;
fBotaoChecked.Top := 7;
fBotaoChecked.Width := 20;
fBotaoChecked.ButtonStyle := pbsNoFrame;
fBotaoChecked.ButtonLayout:= pbsImageCenter;
fBotaoChecked.ImageNormal.LoadFromResourceName(HInstance,'CARGAS_CHECK_VAZIO');
fBotaoChecked.ImageDown.LoadFromResourceName(HInstance,'CARGAS_CHECK_AZUL');
//ReleRadio0
fReleRadio.Parent := Self;
fReleRadio.Left := 130;
fReleRadio.Top := 2;
fReleRadio.Width := 260;
fReleRadio.Height := 30;
fReleRadio.ParentColor := True;
fReleRadio.ParentFont := False;
fReleRadio.TabOrder := 1;
fReleRadio.TabStop := True;
fReleRadio.Font.Size := 7;
fReleRadio.OnClick := OnClickRadioRele;
fReleRadio.Items.Clear;
fReleRadio.Items.Add(LB_CENA_RELE_ACAO_DESLIGAR);
fReleRadio.Items.Add(LB_CENA_RELE_ACAO_LIGAR);
fReleRadio.Items.Add(LB_CENA_RELE_ACAO_INVERTER);
fReleRadio.Items.Add(LB_CENA_RELE_ACAO_PULSAR);
fEditDelay.Parent := Self;
fEditDelay.Left := 400;
fEditDelay.Top := 7;
fEditDelay.Width := 50;
fEditDelay.Height := 24;
fEditDelay.BevelKind := bkFlat;
fEditDelay.Text := '0,0';
fEditDelay.BorderStyle := Forms.bsNone;
fEditDelay.OnKeyPress := EditDelayKeyPress;
fEditDelay.OnExit := EditDelayExit;
fReleRadio.Columns := 4;
fBevelRodape.Parent := Self;
fBevelRodape.Left := 28;
fBevelRodape.Top := 35;
fBevelRodape.Width := 422;
fBevelRodape.Height := 5;
fBevelRodape.Shape := bsBottomLine;
fBevelRodape.Style := bsRaised;
if Assigned(item) then
begin
if TObject(item).ClassType = TFuncaoCena then
begin
funcaoCena := TFuncaoCena(item);
if Trim(TFuncaoCena(item).Nome) <> '' then
fPanelChecked.Caption := TFuncaoCena(item).Nome
else
fPanelChecked.Caption := LB_CARGA+' ' + IntToStr(aIndice + 1);
ReleRadio.ItemIndex := TFuncaoCena(item).Valor;
EditDelay.Text := FormatFloat('##,##0',TFuncaoCena(item).Delay);
if (TFuncaoCena(item).Ativo) then
fBotaoChecked.Checked := True;
end
else if TObject(item).ClassType = TCarga then
begin
Carga := TCarga(item);
if Trim(TCarga(item).Nome) <> '' then
fPanelChecked.Caption := TCarga(item).Nome
else
fPanelChecked.Caption := LB_CARGA+' ' + IntToStr(aIndice + 1);
ReleRadio.ItemIndex := TCarga(item).Valor;
if (TCarga(item).Ativo) then
fBotaoChecked.Checked := True;
end;
end;
fBotaoChecked.Refresh();
Indice := aIndice;
end;
Please, any questions ask me.
Thanks for all help.
There is not enough information to understand, how abstract error arises, but here are some hints about simplifying your code. Sure your
TPanelCargaRele,TPanelCargaDimmer,TPanelDefinicaoCargaAVandTPanelDefinicaoFuncaoSomfyare so much alike, they all contain the same fieldfuncaoCena, so we should use it, defining some general class:Next, why use pointer and cast it to TObject all the time when you can use TObject everywhere. So we can rewrite first function like this:
Hope you get the idea. After code is rewritten, it would be much easier to understand what's wrong.