Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Mehrere erzeute Objekte in Schleife wieder löschen? (https://www.delphipraxis.net/18479-mehrere-erzeute-objekte-schleife-wieder-loeschen.html)

daywalker-dj-k 19. Mär 2004 12:11


Mehrere erzeute Objekte in Schleife wieder löschen?
 
hallo,
ich erzeuge mir folgendermaßen mehrere objekt. quasi 7 objekte in jeder reihe.

Delphi-Quellcode:
procedure TForm1.AuftragNeuenArtikel;
begin
  intAuftragAnzahlEdits := intAuftragAnzahlEdits + 1;
  ScrollBox1.VertScrollBar.Range := 65 + ((intAuftragAnzahlEdits-1) * 100);
  MyLabel := TLabel.Create(self);
  //with TLabel(Form1.FindComponent('NewLabelAuftragPos_' + IntToStr(intAuftragAnzahlEdits))) do
  with MyLabel do
    begin
      Name      := 'NewLabelAuftragPos_' + IntToStr(intAuftragAnzahlEdits);
      Parent    := Form1.ScrollBox1;
      Font.Size := 10;
      Left      := 15;
      Top       := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Caption   := IntToStr(intAuftragAnzahlEdits);
     end;
  MyEdit := TEdit.Create(self);
  //with TEdit(Form1.FindComponent('NewEditAuftragArt_' + IntToStr(intAuftragAnzahlEdits))) do
  with MyEdit do
    begin
      Name := 'NewEditAuftragArt_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 33;
      Left   := 81;
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Text   := 'A';
      MaxLength := 1;
      OnKeyPress := AuftragArtCheck;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
     end;
  MyEdit := TEdit.Create(self);
  //TEdit.Create(Form1).Name := 'NewEditAuftragArtNr_' + IntToStr(intAuftragAnzahlEdits);
  //with TEdit(Form1.FindComponent('NewEditAuftragArtNr_' + IntToStr(intAuftragAnzahlEdits))) do
  with MyEdit do
    begin
      Name := 'NewEditAuftragArtNr_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 60;
      Left   := 142;
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Text   := '';
      OnKeyPress := AuftragArtikel;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
     end;
  //TEdit.Create(Form1).Name := 'NewEditAuftragBez1_' + IntToStr(intAuftragAnzahlEdits);
  //with TEdit(Form1.FindComponent('NewEditAuftragBez1_' + IntToStr(intAuftragAnzahlEdits))) do
  MyEdit := TEdit.Create(self);
  with MyEdit do
    begin
      Name := 'NewEditAuftragBez1_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 350;
      Left   := 245;
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Text := '';
      ReadOnly := True;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
     end;
  //TEdit.Create(Form1).Name := 'NewEditAuftragBez2_' + IntToStr(intAuftragAnzahlEdits);
  //with TEdit(Form1.FindComponent('NewEditAuftragBez2_' + IntToStr(intAuftragAnzahlEdits))) do
  MyEdit := TEdit.Create(self);
  with MyEdit do
    begin
      Name := 'NewEditAuftragBez2_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 350;
      Left   := 245;
      Top    := 112 + ((intAuftragAnzahlEdits-1) * 80);
      Text := '';
      ReadOnly := True;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
   end;

  //TCheckBox.Create(Form1).Name := 'NewCheckBoxAuftragAktion_' + IntToStr(intAuftragAnzahlEdits);
  //with TCheckBox(Form1.FindComponent('NewCheckBoxAuftragAktion_' + IntToStr(intAuftragAnzahlEdits))) do
  MyCheckBox := TCheckBox.Create(self);
  with MyCheckBox do
    begin
      Name := 'NewCheckBoxAuftragAktion_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Left   := 625;
      Caption := '';
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      OnEnter := AuftragAuftragErfassenEditOnEnter;
     end;

  //TEdit.Create(Form1).Name := 'NewEditAuftragMenge_' + IntToStr(intAuftragAnzahlEdits);
  //with TEdit(Form1.FindComponent('NewEditAuftragMenge_' + IntToStr(intAuftragAnzahlEdits))) do
  MyEdit := TEdit.Create(self);
  with MyEdit do
    begin
      Name := 'NewEditAuftragMenge_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 75;
      Left   := 700;
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Text   := '';
      OnKeyPress := AuftrageMengeEnter;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
    end;
end;
diese muss ich dann auch wieder zerstören.

Delphi-Quellcode:
  for i:=1 to intAuftragAnzahlEdits do
    begin
      TLabel(Form1.FindComponent('NewLabelAuftragPos_' + IntToStr(i))).Free;
      TEdit(Form1.FindComponent('NewEditAuftragArt_' + IntToStr(i))).Free;
      TEdit(Form1.FindComponent('NewEditAuftragArtNr_' + IntToStr(i))).Free;
      TEdit(Form1.FindComponent('NewEditAuftragBez1_' + IntToStr(i))).Free;
      TEdit(Form1.FindComponent('NewEditAuftragBez2_' + IntToStr(i))).Free;
      TCheckBox(Form1.FindComponent('NewCheckBoxAuftragAktion_' + IntToStr(i))).Free;
      TEdit(Form1.FindComponent('NewEditAuftragMenge_' + IntToStr(i))).Free;
    end;
    MyLabel := nil;
    MyEdit := nil;
    MyCheckBox := nil;
folgende fehlermeldung erhalte ich dann immer
Delphi-Quellcode:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Project2.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 00403821 in Modul 'Project2.exe'. Lesen von Adresse 0000001C'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------
was mach ich falsch bzw. wie kann man das anders lösen? ich hatte auch schon mal "abstrakte fehler" als meldung bekommen.
wenn ich jetzt einfach alle reihen bis auf die letzte lösche, dann bekomme ich keinen fehler !!! der focus liegt auf keinem der objekte.

danke vielmals
gruß
tkliewe

Leuselator 19. Mär 2004 12:35

Re: Mehrere erzeute Objekte in Schleife wieder löschen?
 
Delphi-Quellcode:
// FormVariablen:
var MyEditList
  , MyChkBoxList
  , MyLabelList : TList;

// beschränke mich i.F. auf die Edits - die anderen Listen strickst Du nach dem selben Muster...
procedure Form1.FormCreate(Sender: TObject);
begin
  MyEditList  := TList.Create;
end;

procedure Form1.CreateTheControls;
begin
  MyEditList.Add(TEdit.Create(Owner))
  with TEdit(MyEditList.Last) do begin
    Parent := DeinParentControl;
    Left := 10;
    // usw.
  end;
end;

procedure Form1.DeleteTheControls;
var i : Integer;
begin
  for i := MyEditList.Count-1 downto 0 do TEdit(MyEditList[i]).Free;
  MyEditList.Clear;
end;

procedure Form1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(MyEditList);
end;
Gruß

Dannyboy 19. Mär 2004 12:45

Re: Mehrere erzeute Objekte in Schleife wieder löschen?
 
Hallo,
für unterschiedliche Edits benötigst Du unterschiedliche Instanzen à la Edit1, Edit2. ... EditN.
Momentan überschreibst Du immer wieder ein und das selbe Editfeld (MyEdit) :!: Dies könnte auch
der Grund der Zugriffsverletzung sein, da hier der von der Instanz (MyEdit) benötigte Speicherplatz überschieben wird, bevor er freigegeben wurde!
Wir erstellen unterschiedliche Edits mal so:
Delphi-Quellcode:
 MyEdit1 := TEdit.Create(self); // EDIT NUMERO 1 !!!
 with MyEdit1 do
    begin
      Name := 'NewEditAuftragArt_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 33;
      Left   := 81;
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Text   := 'A';
      MaxLength := 1;
      OnKeyPress := AuftragArtCheck;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
     end;
  MyEdit2 := TEdit.Create(self);
// hier fängt edit 2 an!!!
  with MyEdit2 do // EDIT NUMERO 2 !!!
    begin
      Name := 'NewEditAuftragArtNr_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 60;
      Left   := 142;
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Text   := '';
      OnKeyPress := AuftragArtikel;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
     end;
So, und danach werden die Edits freigegeben mit: edit1.free und edit2.free.
Frage:
Warum machst Du Dir so'nen Stress mit dynamischen Edits? Warum nicht statisch? :gruebel:

Nachtrag:
Delphi-Quellcode:
//Sowas hier ...
   MyLabel := nil;
   MyEdit := nil;
   MyCheckBox := nil;
//...ersetze bitte durch
  MyLabel.free;
  MyEdit.free;
  MyCheckBox.free;
DANNYBOY

daywalker-dj-k 19. Mär 2004 13:12

Re: Mehrere erzeute Objekte in Schleife wieder löschen?
 
hallo,
hab jetzt die erstellung der objekt so umgeschrieben. allerdings funktionieren die ereignisse nicht mehr richtig. ich erhalte immer einen fehlermeldung (zugriffverletzung).

Delphi-Quellcode:
  MyEditList.Add(TEdit.Create(Owner));
  with TEdit(MyEditList.Last) do
    begin
      Name := 'NewEditAuftragArt_' + IntToStr(intAuftragAnzahlEdits);
      Parent := Form1.ScrollBox1;
      Font.Size := 10;
      Width := 33;
      Left   := 81;
      Top    := 80 + ((intAuftragAnzahlEdits-1) * 80);
      Text   := 'A';
      MaxLength := 1;
      OnKeyPress := AuftragArtCheck;
      OnEnter := AuftragAuftragErfassenEditOnEnter;
      OnChange := AuftragAuftragErfassenEditOnEnter;
     end;
woran könnte das liegen?

danke
mfg
tkliewe

Leuselator 19. Mär 2004 13:54

Re: Mehrere erzeute Objekte in Schleife wieder löschen?
 
Du mußt "Owner" durch den tatsächlichen gewünschten Owner (Form1?) ersetzen denke ich
Das folgende funzt tadellos:
Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure AuftragArtCheck(Sender: TObject; var Key: Char);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
   procedure DeleteTheControls;
   procedure CreateTheControls;
  end;

var Form1: TForm1;
    MyEditList
  , MyChkBoxList
  , MyLabelList : TList;

implementation

{$R *.DFM}


// beschränke mich i.F. auf die Edits - die anderen Listen strickst Du nach dem selben Muster...
procedure TForm1.FormCreate(Sender: TObject);
begin
  MyEditList  := TList.Create;
end;

procedure TForm1.CreateTheControls;
begin
  MyEditList.Add(TEdit.Create(self));
  with TEdit(MyEditList.Last) do begin
      Name := 'NewEditAuftragArt_1';
      Parent := Form1.Panel1;
      Font.Size := 10;
      Width := 33;
      Left   := 81;
      Top    := 80;
      Text   := 'A';
      MaxLength := 1;
      OnKeyPress := AuftragArtCheck;
//      OnEnter := AuftragAuftragErfassenEditOnEnter;
//      OnChange := AuftragAuftragErfassenEditOnEnter;
  end;
end;

procedure TForm1.DeleteTheControls;
var i : Integer;
begin
  for i := MyEditList.Count-1 downto 0 do TEdit(MyEditList[i]).Free;
  MyEditList.Clear;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(MyEditList);
end;



procedure TForm1.AuftragArtCheck(Sender: TObject; var Key: Char);
begin
//
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateTheControls;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 DeleteTheControls;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:42 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