EReadError bei eigener Komponente (war: Ich weiß nicht mehr weiter)



  • Warum will mir keiner helfen?



  • Mir ist aufgefallen, dass Du nirgendwo FBild initialisierst, weshalb u.U. die entsprechende Set-Methode
    fehlschlagen könnte.

    Mein Vorschlag:

    __fastcall TMyBild::TMyBild(TComponent* Owner): 
      TGraphicControl(Owner),
      FBild(0)
    {   }
    

    Insgesamt könnte Dein Code sicherlich noch etwas überarbeitet werden 😉

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    Mir ist aufgefallen, dass Du nirgendwo FBild initialisierst, weshalb u.U. die entsprechende Set-Methode
    fehlschlagen könnte.

    das macht er in der Set Methode.

    Ich würde aber auch in Constructor das Bild erzeugen und im Destructor deleten!
    Ich denk auch , dass der Fehler irgendwie damit zu tun hat.



  • Versuch mal stored=true zu setzen bei deinem Image. Hier Beispiel bei StringList:

    __property TStringList* FixedColsText = { read=FFixedColsText, write=SetFixedColsText,stored=true};



  • DerAltenburger schrieb:

    Alexander Kempf schrieb:

    Mir ist aufgefallen, dass Du nirgendwo FBild initialisierst, weshalb u.U. die entsprechende Set-Methode
    fehlschlagen könnte.

    das macht er in der Set Methode.

    Ich glaube, das geht da schief.
    Nehmen wir an FBild zeigt irgendwohin (nicht sauber auf 0 initialisiert):

    thunderbol5 schrieb:

    void __fastcall TMyBild::SetBild(Graphics::TBitmap * Value)
    {
      // Hoffen wir das was vernünftiges übergeben wird, d.h. Value != 0 (NULL)...
      if(Value == NULL){//...dann ist diese Bedingung false, d.h. es geht unten weiter...
    
        if (FBild)
          FBild = NULL;
        return;
      };
    //...hier geht's weiter und FBild zeigt irgendwohin,...
      if(!FBild) //...d.h. !FBild ist false und...
        FBild = new Graphics::TBitmap; //...dieser Befehl wird nicht abgearbeitet
    // hier zeigt FBild immer noch irgendwohin, wohin weiß nur der liebe Gott
      FBild->Assign(Value);  // Was passiert dann?
      Invalidate();
    }
    

    Oder liege ich total daneben?
    Das müsste sich aber durch Debuggen herausfinden lassen - sofern man weiß, wie man Komponenten
    debuggt...

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    Ich glaube, das geht da schief.

    Ich sag ja, ich mach das auch lieber im Constructor/Destructor.



  • DerAltenburger schrieb:

    Ich sag ja, ich mach das auch lieber im Constructor/Destructor.

    Ich glaube nicht, dass das was mit Vorlieben zu tun hat.
    Wenn man im Konstruktor nicht sauber initialisiert, verlässt man sich auf den Zufall - ziemlich
    riskant.
    Die Frage bleibt natürlich, ob's in dem Fall daran liegt.

    Gruß,

    Alexander



  • Hallo Alexander Kempf, Der Altenburger, Christian211

    erstmal vielen Dank für Eure Mithilfe. Hatte zwischenzeitlich schon nicht mehr damit gerechnet eine Antwort in diesem Forum zu bekommen, obwohl ich mir ja richtig Mühe gemacht hatte.

    Ich habe mittlerweile das Problem gelöst. Die Kompo funktioniert jetzt einwandfrei.

    Ihr hattet Recht.

    Der Fehler liegt tatsächlich im Konstruktor. Dort muss eine Variable vom Typ TBild angelegt sein, wenn ein Bild aus dem Objektinspektor geladen werden soll.
    Ich hatte ursprünglich angenommen, dass die Übergabe eines Bitmaps, das vom Objektinspektor geladen wurde, in der Set-Funktion auf die Kompo geschieht. Das scheint aber nicht so zu sein bzw. zu funktionieren.
    Bei anderen Property-Typen wie z.B int, bool scheint eine Initialisierung im Konstruktor nicht notwendig zu sein.

    Ich habe das so gelöst:

    __fastcall TMyBild::TMyBild(TComponent* Owner):TGraphicControl(Owner){
    ...
    if (!FBild) FBild = new Graphics::TBitmap;
    ...
    }
    

    Dadurch ist in der Funktion

    void __fastcall TMyBild::SetBild(Graphics::TBitmap* Value)
    

    die Anweisung

    if (!FBild) FBild = new Graphics::TBitmap;
    

    natürlich überflüssig, da sie ja bereits im Konstruktor durchgeführt wird und die Variable erst beim Verlassen der Kompo gelöscht wird.

    __fastcall TMyBild::BeforeDestruction(void){
    if (FBild) delete FBild;
    }
    


  • thunderbol5 schrieb:

    Ich habe das so gelöst:

    __fastcall TMyBild::TMyBild(TComponent* Owner):TGraphicControl(Owner){
    ...
    if (!FBild) FBild = new Graphics::TBitmap;
    ...
    }
    

    Meines Erachtens ist hier die Überprüfung !FBild naturlich genauso falsch. Woher sollte denn im
    Konstruktor der Wert für FBild gesetzt sein? Auch dort wird er wohl irgendwo hinzeigen.
    Korrekt wäre z.B.:

    __fastcall TMyBild::TMyBild(TComponent* Owner):
      TGraphicControl(Owner),
      FBild(new Graphics::TBitmap())
    {
    ...
    }
    

    Falsch bzw. nicht initialisierte Zeiger sind immer wieder Anlass für schwer nachvollziehbare
    Fehler und Abstürze. Ich habe mir angewöhnt, jede Membervariable auf die oben gezeigte Art zu
    initialisieren. Zeiger entweder auf 0 oder auf eine neu erzeugte Instanz. Alles andere ist
    Zufallsprogrammierung.

    Gruß,

    Alexander



  • Hallo Alexander Kempf 👍

    Überzeugt!
    Habe Deinen Rat aufgenommen und den Konstruktor entsprechend umgebaut.


Anmelden zum Antworten