mal wieder was zu ReadComponent



  • Hi, hab in den FAQs schon viel Hilfe zu dem Thema gefunden besonderen Dank dafür an AndreasW. Habe trotz allem noch Schwierigkeiten mit der Implementierung von ReadComponent. Ich schreibe ein mit new erzeugtes Formular auf dem eine TScrollbox dargestellt wird mit WriteComponent in eine Datei. Das sieht dann so aus.

    object Basis: TForm2
    Left = -4
    Top = -23
    Width = 870
    Height = 592
    Caption = 'Basis'
    Color = clBtnFace
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    FormStyle = fsMDIChild
    OldCreateOrder = False
    Visible = True
    WindowState = wsMaximized
    OnClose = FormClose
    PixelsPerInch = 96
    TextHeight = 13
    object ScrollBox1: TScrollBox
    Left = 0
    Top = 0
    Width = 729
    Height = 513
    TabOrder = 0
    end
    end

    Beim laden des Ganzen mit ReadComponent bekomme ich dann folgende Fehlermeldung.

    Im Projekt Project1.exe ist eine Exception der Klasse EComponentError aufgetreten. Meldung: 'Komponente mit der Bezeichnung ScrollBox1 existiert bereits'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.

    Hab aus den FAQ-Beiträgen die LoadComponentFromFile Methode genutzt und rufe sie Form1 aus auf.

    void __fastcall TForm1::laden1Click(TObject *Sender)
    {
            TForm2 *TestForm=new TForm2(this);
            TestForm->Parent = this;
            RegisterClass(__classid(TScrollBox));
            if(LoadComponentFromFile("Basis", TestForm))
            TestForm->Show();
    }
    

    Kann mir jemand sagen wie ich das Formular ohne Fehler wieder laden kann?



  • Hallo,

    Da ReadComponent bei Erfolg eine neue Komponente erzeugt gibt es natürlich einen Fehler wenn eine Komponente gleichen Namens schon existiert. Du könntest deine alte Komponente vorher löschen (aus der Komponentenlist entfernen).

    Ciao



  • die ScrollBox wird aber zur Entwurfszeit in das Formular gepackt. wie kann man denn zur Laufzeit die Scrollbox aus der Komponentenliste nehmen?



  • und noch was zu dem Thema...
    wenn ich die ScrollBox, ein TImage oder sonstwas zur Laufzeit erzeuge, schreibe und wieder lade geht alles wie am Schnürchen. Das Problem ist dann nur, daß zwar die Scrollbox aber nicht das Bild in der Box gespeichert wird.

    void __fastcall TForm1::Create1Click(TObject *Sender)
    {
            //Form erzeugen
            TForm2* lpfrmBasis = new TForm2(this);
            lpfrmBasis->Parent = MDIChildren[0];
            lpfrmBasis->Name = "Basis";
            //ScrollBox erzeugen
            TScrollBox* lpSBxActive = new TScrollBox(lpfrmBasis);
            lpSBxActive->Parent = lpfrmBasis;
            //Image in ScrollBox packen
            TImage* lpImgActive = new TImage(lpSBxActive);
            lpImgActive->Parent = lpSBxActive;
            lpImgActive->SetSubComponent(true);
            //dem Imageobjekt ein Bild zuweisen
            TPicture* lppicActive = new TPicture();
            OpenPictureDialog1->Execute();
            lppicActive->LoadFromFile(OpenPictureDialog1->FileName);
            lpImgActive->Picture = lppicActive;
    }
    


  • Hast Du schon mal versucht, TestForm nicht per new zu erstellen?
    Die Form soll ja schließlich geladen werden (wobei ich den Sinn
    dahinter nicht verstehe).
    Also, z.B.:

    void __fastcall TForm1::laden1Click(TObject *Sender)
    {
            TForm2 *TestForm; //=new TForm2(this);
            TestForm->Parent = this;
            RegisterClass(__classid(TScrollBox));
            if(LoadComponentFromFile("Basis", TestForm))
            TestForm->Show();
    }
    

    Gruß,

    Alexander



  • hab auch ohne das Formular zu erzeugen probiert das Objekt aus der Datei zu laden. Der Effekt bleibt der selbe 😞



  • Hast Du auch schon mal versucht, TestForm einen anderen Typ zu geben?
    Wenn Du TestForm vom Typ TForm2 hast, dann ist natürlich automatisch
    auch Deine ScrollBox darauf.
    LoadComponent funktioniert dann aber nur, wenn TForm2 dem ClassLoader bekannt
    ist.

    TForm *TestForm;
    

    Gruß,

    Alexander



  • so, ich erzeuge jetzt die Komponenten zur Laufzeit. dann wird es ja korrekt hin und hergespeichert. Das Problem was jetzt noch bleibt ist, wie ich die in Behälter eingebetteten Objekte mit speichern kann. Bsp.: TImage in TScrollbox wird nicht mitgespeichert auch wenn ich es als Subkomponente freigebe.
    Wenn jemand dafür 'ne Lösung hätte...



  • Sprotti schrieb:

    so, ich erzeuge jetzt die Komponenten zur Laufzeit.

    Vielleicht kannst Du mal zeigen, wie Du das machst.

    Sprotti schrieb:

    dann wird es ja korrekt hin und hergespeichert.

    Daran habe ich Zweifel.

    Sprotti schrieb:

    Das Problem was jetzt noch bleibt ist, wie ich die in Behälter eingebetteten Objekte mit speichern kann.

    Das verstärkt meine Zweifel noch.

    Wenn Du das Ganze so angehst, wie Du's oben schon mal gezeigt hast - also
    Instanziierung eines Objekts vom Typ TForm2 - dann vermute ich, daß zu diesem
    Zeitpunkt schon eine TScrollBox-Komponente auf Deinem Formular existiert.
    (Das läßt sich überprüfen, indem Du mal alles nach der Erzeugung wegläßt und
    das Objekt mit WriteComponent() speicherst)
    Wenn Du später die Komponente schreibst, bekommst Du (vermutlich) mehr oder
    weniger eine Kopie Deiner DFM-Datei von TForm2.
    Um das zu überprüfen, könntest Du mal ein Formular-Objekt vom Standardtyp TForm
    erstellen und den Rest wie gehabt lassen. Wenn dann in der gespeicherten Datei
    die ScrollBox-Komponente fehlt, stimmen meine Vermutungen wahrscheinlich. Ist
    die Komponente vorhanden, dann kannst Du ja mal noch mit InsertComponent() rum-
    experimentieren.
    Vielleicht liege ich mit meinen Vermutungen daneben, aber einen Versuch ist's
    ja wert, wenn Du Dich schon so lange damit beschäftigst.

    Gruß,

    Alexander



  • habe es auch mit TForm probiert. Auch hier erhalte ich eine Fehlermeldung.

    ... eine Exception der Klasse EReadError aufgetreten. Meldung: 'Ungültiger Eigenschaftswert'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.

    @Alexander: Deine Zweifel sind unbegründet. Wenn ich die Komponenten so wie oben erzeuge, wird Form und Scrollbox korrekt gespeichert und geladen. Nur das Image eben nicht.

    ... vermute ich das zu diesem Zeitpunkt schon eine Scrollbox existiert

    das Form2 ist zu diesem Zeitpunkt komplett leer. (könnte also auch TForm sein)

    Hier noch die gespeicherte Datei

    object Basis: TForm2
      Left = 0
      Top = 0
      Width = 682
      Height = 385
      Caption = 'Basis'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      FormStyle = fsMDIChild
      OldCreateOrder = False
      Visible = True
      OnClose = FormClose
      PixelsPerInch = 96
      TextHeight = 13
      object TScrollBox
        Left = 0
        Top = 0
        Width = 185
        Height = 41
        TabOrder = 0
      end
    end
    


  • Die Fehlermeldung ist ja relativ eindeutig und läßt für mich nur drei
    Interpretationen offen:
    Im Falle, daß das Objekt (=Formular-Variable), in das Du die Komponente lädst,
    keine Komponente mit Namen ScrollBox1 enthält:
    1. Deine Lade-Routinen enthalten einen Fehler (weiß ich nicht - kenne Deinen
    Quellcode nicht) und Du lädst aus irgendwelchen Gründen die Komponente zweimal.
    2. Die Lade-Routinen von Borland haben einen Bug (aus meiner eigenen Erfahrung
    mit den Routinen relativ unwahrscheinlich) und laden die Komponente zweimal.

    Andernfalls:
    3. Das Objekt (=Formular-Variable), in das Du die Komponente lädst enthält bereits
    eine Komponente mit Namen ScrollBox1 und Du hast noch irgendwas übersehen.

    Kann natürlich sein, daß es noch andere Interpretationen gibt, aber ich sehe keine
    anderen. Möglichkeit 2 ist die bequemste, da dies bedeuten würde, daß Du keinen
    Fehler gemacht hast. Leider würde Dich das nicht weiterbringen und es würde mich
    sehr verwundern, wenn in so grundlegenden Dingen ein Bug drin wäre.
    Also würde ich empfehlen, Dich auf die anderen Möglichkeiten zu stürzen.
    Mein heißer Favorit ist nach wie vor 3. - auch wenn Du das vollkommen ablehnst.

    Gruß,

    Alexander



  • Ich habe gerade mal die von Dir generiert Objekt-Datei in einem Testprogramm
    von mir ausprobiert und konnte das Formular ohne Fehler laden. Dabei lösche
    ich allerdings beim Einlesen die Event-Behandlungsroutinen und benenne den
    Formulartyp in TForm - also den Standardtyp - um.

    Gruß,

    Alexander



  • Habe gerade gesehen, daß Du noch was in Deinem posting ergänzt hast.

    Sprotti schrieb:

    habe es auch mit TForm probiert. Auch hier erhalte ich eine Fehlermeldung.

    ... eine Exception der Klasse EReadError aufgetreten. Meldung: 'Ungültiger Eigenschaftswert'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.

    Das liegt wahrscheinlich an der Zeile

    FormStyle = fsMDIChild
    

    in Deiner Objekt-Datei. Entweder mußt Du die Form von einem MDI-Fenster aus
    laden oder die Zeile beim Einlesen löschen.

    Gruß,

    Alexander



  • Hallo, habe das Problem jetzt endlich gelöst. Der Grund für die Fehlermeldung das die Objekte die ich reinladen wollte schon vorhanden wären, lag wirklich daran, daß die Komponenten nicht aus der .dfm Datei gelesen werden durften. Das erreicht man durch den Form Konstruktor TForm(Owner, Dummy). Hierbei dient der Dummy nur zur Unterscheidung der Konstruktoren.
    Vielen Dank an alle Hilfsbereiten 👍


Anmelden zum Antworten