2016-03-28 2 views
-1

Я столкнулся с Abstract error, когда я перетаскиваю дочерний элемент TPanel в компонент TImage.«Абстрактная ошибка» при перетаскивании дочернего элемента TPanel

В основном у меня есть 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; 

Пожалуйста, любые вопросы, спрашивайте.

Спасибо за помощь.

+1

Попробуйте некоторые отладки –

+0

Этот код является ужасным, и ему не хватает всех определений классов, которые необходимы, чтобы попытаться воссоздать проблему. Вам нужно будет отладить это самостоятельно, введя методы, пока не сузите проблему. –

+0

Почему это происходит с использованием таких уродливых типов-указаний типа «Pointer» и «ClassType», вместо использования фактических типизированных переменных и 'is' /' as' операторов? –

ответ

1

Недостаточно информации, чтобы понять, как возникает абстрактная ошибка, но вот несколько советов об упрощении кода. Конечно ваш TPanelCargaRele, TPanelCargaDimmer, TPanelDefinicaoCargaAV и TPanelDefinicaoFuncaoSomfy настолько похожи друг на друга, все они содержат такое же поле funcaoCena, поэтому мы должны использовать его, определив некоторые общий класс:

Далее, почему использовать указатель и приведение его в 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; 

Надеюсь, у вас возникнет эта идея. После того, как код будет переписан, было бы намного легче понять, что случилось.

+0

Благодарим за помощь. Вместо других вы пытаетесь мне помочь. Большое спасибо. –

+0

Мы все помогаем вам. Если вы хотите, чтобы мы сказали вам, что ваш код будет в порядке с помощью нескольких настроек, это вам не поможет. Это усугубит ситуацию, продлит агонию. Ваш код является непревзойденной катастрофой, и у вас есть большой дефицит знаний. Чем скорее вы это признаете, тем скорее вы сможете исправить их. –

Смежные вопросы