AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Komponenten dynamisch erzeugen = ok, free = nicht ok
Thema durchsuchen
Ansicht
Themen-Optionen

Komponenten dynamisch erzeugen = ok, free = nicht ok

Offene Frage von "torud"
Ein Thema von torud · begonnen am 16. Mär 2005 · letzter Beitrag vom 16. Mär 2005
Antwort Antwort
Seite 1 von 2  1 2      
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#1

Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 11:18
Hallo Leute!

Ich habe die Suche bedient und einiges zu diesem Thema gefunden. Leider hat es nichts gebracht.

Mit folgender Prozedure erzeuge ich auf einer Scrollbox dynamisch DBEdits und Labels, nachdem ich eine Datenbank geladen habe. Nicht unbedingt schön, aber es funzt.

Delphi-Quellcode:
procedure TForm1.TrytoCreateDBFields; //dynamisches erzeugen
var
  i:integer;
  DBEdit:TDBEdit;
  Labels:TLabel;
  scr_dbfields:TScrollBox;
begin
  scr_dbfields.Free;
  scr_dbfields := TScrollbox.Create(self);
  scr_dbfields.Parent:=TabSheet7;
  scr_dbfields.Align:=alClient;

  with scr_dbfields do begin
   for i:=0 to Table1.FieldCount-1 do
     begin
       case Table1.Fields.Fields[i].DataType of
         ftString,ftInteger, ftAutoInc, ftSmallint, ftFloat,ftWord :
         begin
          //label erzeugen
          Labels:= TLabel.Create(self);
          Labels.Parent := scr_dbfields;
          Labels.Left :=10;
          Labels.Top := i * 30;
          Labels.Caption:=Table1.FieldList.Strings[i];
          //dbfeld erzeugen
          DBEdit:= TDBEdit.Create(self);
          DBEdit.Parent := scr_dbfields;
          DBEdit.Left :=100;
          DBEdit.Top := i * 30;
          DBEdit.DataSource:=DataSource1;
          DBEdit.Name:=Table1.FieldList.Strings[i];
          DBEdit.DataField:=Table1.FieldList.Strings[i];
        end;
       end;
     end;
  end;
end;

Delphi-Quellcode:
procedure TForm1.DestroymyDBKompos; //dynamisches freigeben
var
  i:integer;
begin
i:= 0;
  while i<scr_dbfields.parent.ComponentCount do
    if (scr_dbfields.parent.Components[i] is TDBEdit) or ((scr_dbfields.parent.Components[i] is TLabel)) then scr_dbfields.parent.Components[i].Free
    else Inc(i);
end;

Wenn ich nun auf eine FileListBox doppelt klicke und versuche eine neue DB zu öffnen erhalte ich immer wieder eine Fehlermeldung.

Delphi-Quellcode:
procedure TForm1.FileListBox1DblClick(Sender: TObject);
begin
        Table1.Active:=False;
        Table1.DatabaseName:=DirectoryListBox1.Directory;
        Table1.TableName:=FileListBox1.Items.Strings[FileListBox1.ItemIndex];
        DestroymyDBKompos; //zerstören der kompos
        //scr_dbfields.Free;
        ShowMessage('kaput');
        Table1.Active:=True;
        ed_header.Text:=FileListBox1.Items.Strings[FileListBox1.ItemIndex];
        TrytoCreateDBFields; //neues generieren der kompos
end;
Die Prozedur DestroymyDBKompos soll sich darum kümmern, dass die oben erzeugten Komponenten wieder freigeben werden, damit wieder neue komponenten erzeugt werden können.

Das Ganze funktioniert nur einmal nach dem Programmstart. Wenn ich dann eine andere DB laden willerhalte ich immer wieder eine Fehlermeldung, dass irgendein DB-Feld nicht gefunden wurde. Das passiert aber nur, wenn ich DestroymyDBKompos oder/und TrytoCreateDBFields versuche zu benutzen.

Was mache ich denn da falsch???
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von jim_raynor
jim_raynor

Registriert seit: 17. Okt 2004
Ort: Berlin
1.251 Beiträge
 
Delphi 5 Standard
 
#2

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 11:40
Du darfst nicht scr_dbfields.Free machen. scr_dbfields ist doch undefiniert und dann dort den Speicher freigeben? Das ist ganz böse und an dieser Stelle auch überflüssig, da du noch gar kein Objekt hast. Eventuell solltest du es als globale Variable definieren und mit nil initsialisieren.

Kann es sein dass du dbfields schon als Globale Variable hast? Dann sollest du die Variable in TrytoCreateDBFields löschen
Christian Reich
Schaut euch mein X-COM Remake X-Force: Fight For Destiny ( http://www.xforce-online.de ) an.
  Mit Zitat antworten Zitat
Benutzerbild von Orbmu2k
Orbmu2k

Registriert seit: 29. Nov 2004
Ort: Erfurt
254 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 11:41
versuchs mal so ... (ungetestet)

Delphi-Quellcode:
procedure TForm1.DestroymyDBKompos; //dynamisches freigeben
var
  i:integer;
begin
  for i := scr_dbfields.parent.ComponentCount-1 downto 0 do
    if (Assigned(cr_dbfields.parent.Components[i]))
      and ((scr_dbfields.parent.Components[i] is TDBEdit)
        or (scr_dbfields.parent.Components[i] is TLabel))
          then
            FreeAndNil(scr_dbfields.parent.Components[i]);
end;
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#4

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 11:49
Danke für die Infos!

Bei dem Codeversuch habe ich eine Fehlermeldung erhalten, die besagt, dass das "Konstantenobjekt nicht als Var-Parameter weitergegeben werden kann". Diese Meldung bezieht sich auf die letzte zeile FreeandNil...

und @ jim

scr_dbfields ist doch die Scrollbox, auf der ich die Kompos ablege. Ich dachte eigentlich, dass es reichen könnte, wenn ich diese Scrollbox freigeben und sich das Programm der Kompos darauf selbst entledigt...Dem war nicht so.

Warum ist denn scr_dbfields undefiniert?

und, TrytoCreateDBFields ist eine Prozedur und keine Variable!
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von Orbmu2k
Orbmu2k

Registriert seit: 29. Nov 2004
Ort: Erfurt
254 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 11:56
Ok dann mach aus dem FreeAndNil wieder eine normales Free
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#6

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 12:03
ok, nun mecker zumindest nicht mehr der Compiler, beim Erstellen der exe.

Aber ich bekomme immer noch eine Fehlermeldung. Und zwar versucht das Programm beim Zerstören noch auf Datenbankbestandteile zuzugreifen, vermute ich zumindest, denn in der Fehlermeldung steht immer wieder, dass "Das Feld Text wurde nicht gefunden" Dies ist in dem Fall das letzte Datenbankfeld.

Diese Meldung kommt nur, wenn ich versuche DestroymyDBKompos ausführen zu lassen. Wenn ich mir davor eine Message anzeigen lasse ist alles ok.

Und noch ein kleines Problem. Ich habe die Prozedure ein wenig umgebaut, weil ich einfach checken wollte, wo der Fehler liegen könnte.

Delphi-Quellcode:
procedure TForm1.DestroymyDBKompos;
var
  i:integer;
begin
i:= 0;
  for i := scr_dbfields.parent.ComponentCount-1 downto 0 do
    if (Assigned(scr_dbfields.parent.Components[i]))
      and ((scr_dbfields.parent.Components[i] is TDBEdit)
        or (scr_dbfields.parent.Components[i] is TLabel))
          then
            begin ShowMessage(scr_dbfields.parent.Components[i].Name);
            scr_dbfields.parent.Components[i].Free;
            end;
end;
Die Messagebox erhalte ich nicht, denn es kommt vorher die Meldung, wie oben beschrieben. Hm, muss ich die Komponenten vorher noch von der DB lösen???
Danke
Tom
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#7

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 12:27
Ich habe beim Debuggen noch herausbekommen, dass obwohl mindestens 3 Komponenten auf der Scollbox vorhanden sind der scr_dbfields.parent.ComponentCount = 0 ist. Kann es sein, dass die Obejkte nicht korrekt als Childs zugewiesen werden und dadurch die Probleme entstehen?

Zumindest habe ich nun die Prozedur zum Erstellen so abgeändert, dass der Count hinhaut und das die Controls dem scr_dbfields als Childs zugewiesen werden.

Delphi-Quellcode:
procedure TForm1.TrytoCreateDBFields;
var
  i:integer;
  DBEdit:TDBEdit;
  Labels:TLabel;
  scr_dbfields:TScrollBox;
begin
  scr_dbfields.Free;
  scr_dbfields := TScrollbox.Create(TabSheet7);
  scr_dbfields.Parent:=TabSheet7;
  scr_dbfields.Align:=alClient;

  with scr_dbfields do begin
   for i:=0 to Table1.FieldCount-1 do
     begin
       case Table1.Fields.Fields[i].DataType of
         ftString,ftInteger, ftAutoInc, ftSmallint, ftFloat,ftWord :
         begin
          //label erzeugen
          Labels:= TLabel.Create(scr_dbfields);
          Labels.Parent := scr_dbfields;
          Labels.Left :=10;
          Labels.Width:=85;
          Labels.Alignment:=taRightJustify;
          Labels.Top := (i * 30)+3;
          Labels.Caption:=Table1.FieldList.Strings[i];
          //dbfeld erzeugen
          DBEdit:= TDBEdit.Create(scr_dbfields);
          DBEdit.Parent := scr_dbfields;
          DBEdit.Left :=100;
          DBEdit.Top := i * 30;
          DBEdit.DataSource:=DataSource1;
          DBEdit.Name:=Table1.FieldList.Strings[i];
          DBEdit.DataField:=Table1.FieldList.Strings[i];
          ShowMessage(inttostr(scr_dbfields.ComponentCount))
        end;
       end;
     end;
  end;
end;
Trotzdem kommt immer noch die Fehlermeldung, dass er das letzte DB-Feld nicht finden kann.
Danke
Tom
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#8

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 13:02
An Alle, die es noch interessiert!

Das Problem ist nicht das löschen der Controls, sondern tritt erst beim Zuweisen des DataFields auf. Wenn ich diese Zeile auskommentiere wird alles immer korrekt erstellt und gelöscht. Das Problem ist, dass diese Zuweisung aber für die Anbindung an die DB wichtig ist.

aus der Prozedur TrytoCreateDBFields
DBEdit.DataField:=Table1.FieldList.Strings[i]; schon komisch oder?
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von Orbmu2k
Orbmu2k

Registriert seit: 29. Nov 2004
Ort: Erfurt
254 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 13:04
versuch mal das

  DBEdit.DataField:=Table1.FieldDefs[i].DisplayName;
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#10

Re: Komponenten dynamisch erzeugen = ok, free = nicht ok

  Alt 16. Mär 2005, 13:09
Danke für den Tipp, aber das Problem ist das GLEICHE!

Kann es sein, dass ich vorher noch die Fieldlist löschen muss?

Das komische ist, wenn ich mir

Delphi-Quellcode:
          ShowMessage(Table1.FieldDefs[i].DisplayName);
          //DBEdit.DataField:=Table1.FieldDefs[i].DisplayName;
das vorher anzeigen lasse, zeigt er mir die richtigen Feldnamen an. Versuche ich es zuzuweisen, erhalte ich nicht einmal mehr diese Messagebox.
Danke
Tom
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz