"Abstract error" 当拖放 TPanel 子项时
"Abstract error" when Drag and drop TPanel child
当我在 TImage
组件中拖放 TPanel 子项时,我正面临 Abstract error
。
基本上我有一个 Scrollbox
包含一个 TPanelCargaRele
列表,当我将此面板拖放到废纸篓时,我得到 Abstract error
.
我调试了我的代码,但这个问题发生在程序的 end;
行,我看不出问题出在哪里。
下面是我的代码:
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..
这里是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;
有什么问题可以问我
感谢大家的帮助。
没有足够的信息来理解抽象错误是如何产生的,但这里有一些关于简化代码的提示。
当然你的TPanelCargaRele
、TPanelCargaDimmer
、TPanelDefinicaoCargaAV
和TPanelDefinicaoFuncaoSomfy
很像,它们都包含相同的字段funcaoCena
,所以我们应该使用它,定义一些一般 class:
TPanelWithCena = class (TPanel)
public
funcaoCena: TFuncaoCena;
end;
TPanelCargaRele = class (TPanelWithCena)
....
TPanelCargaDimmer = class (TPanelWithCena)
...
接下来,当您可以在任何地方使用 TObject 时,为什么要一直使用指针并将其强制转换为 TObject。所以我们可以这样重写第一个函数:
function getFuncaoCena(p: TObject): TFuncaoCena;
begin
if Assigned(p) then
begin
if p is TPanelWithCena then
Result:=TPanelWithCena(p).funcaoCena
else if p is TWinControl then
Result:=getFuncaoCena(TWincontrol(p).Parent)
else
Result:=nil;
else
Result := nil;
end;
希望你明白了。重写代码后,更容易理解哪里出了问题。
当我在 TImage
组件中拖放 TPanel 子项时,我正面临 Abstract error
。
基本上我有一个 Scrollbox
包含一个 TPanelCargaRele
列表,当我将此面板拖放到废纸篓时,我得到 Abstract error
.
我调试了我的代码,但这个问题发生在程序的 end;
行,我看不出问题出在哪里。
下面是我的代码:
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..
这里是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;
有什么问题可以问我
感谢大家的帮助。
没有足够的信息来理解抽象错误是如何产生的,但这里有一些关于简化代码的提示。
当然你的TPanelCargaRele
、TPanelCargaDimmer
、TPanelDefinicaoCargaAV
和TPanelDefinicaoFuncaoSomfy
很像,它们都包含相同的字段funcaoCena
,所以我们应该使用它,定义一些一般 class:
TPanelWithCena = class (TPanel)
public
funcaoCena: TFuncaoCena;
end;
TPanelCargaRele = class (TPanelWithCena)
....
TPanelCargaDimmer = class (TPanelWithCena)
...
接下来,当您可以在任何地方使用 TObject 时,为什么要一直使用指针并将其强制转换为 TObject。所以我们可以这样重写第一个函数:
function getFuncaoCena(p: TObject): TFuncaoCena;
begin
if Assigned(p) then
begin
if p is TPanelWithCena then
Result:=TPanelWithCena(p).funcaoCena
else if p is TWinControl then
Result:=getFuncaoCena(TWincontrol(p).Parent)
else
Result:=nil;
else
Result := nil;
end;
希望你明白了。重写代码后,更容易理解哪里出了问题。