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
endBeim 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