Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Panels dynamisch erzeugen -> Ungültige Zeigeroperation (https://www.delphipraxis.net/34669-panels-dynamisch-erzeugen-ungueltige-zeigeroperation.html)

mika 26. Nov 2004 10:57


Panels dynamisch erzeugen -> Ungültige Zeigeroperation
 
Hallo an alle,

ich habe folgendes Problem beim dynamischen erzeugen und freigeben eines Objektes vom Typ TPanel.
Ich muss auf einer Scrollbox soviele Panels zeichnen wie Datensätze in einer Tabelle sind,
soweit alles ganz klar, aber beim freigeben der Panels bekomme ich eine "Ungültige Zeigeroperation".

Hier mal n bissle code:

Variablen
Code:
const
  myLKWBreite = 175;
  myLKWHoehe = 350;
  myLKWAbstand = 10;

var
  myLKW : Array OF TMyLKWObjekt;
Die Klasse
Code:
  TMyLKWObjekt = class(TPanel)

  (* Konstruktor / Dekonstruktor *)
  Constructor myCreate(lkwID: Integer);
  Destructor myDestroy;

  (* private deklaration *)
  private
    id: Integer;

  (* oeffentliche deklaration *)
  public

  end;
Konstruktor / Destruktor
Code:
Constructor TMyLKWObjekt.myCreate(lkwID: Integer);
Begin
  // Erst mal das Hauptpanel erzeugen
  Create     (frmTourenplan.sbTouren);
  Parent     := frmTourenplan.sbTouren;
  id         := lkwID;
End;

Destructor TMyLKWObjekt.myDestroy;
Begin
  // Ein LKW Objekt freigeben
  Inherited Destroy;
End;
Code zum erzeugen der Panels - Klappt auch ganz wunderbar
Code:
procedure TfrmTourenplan.LkwPanelsErzeugen;
Var
  i: integer;
  links, oben: Integer;

begin
  // Ggf. erst alte LKW's wieder freigeben

  // Neue Lkw's anlegen
  I := 0;

  tblLKW.Refresh;
  tblLkw.First;
  SetLength(myLKW, tblLKW.RecordCount - 1);

  Links := myLKWAbstand;
  Oben := myLKWAbstand;
  while not tblLkw.Eof do
  begin
    // LKW Panel erzeugen
    myLKW[i] := TMyLKWObjekt.myCreate(i);

    with myLKW[i] do
    begin
      // LKW Panel ausrichten
      SetBounds(Links, Oben, myLKWBreite, myLKWHoehe);

      // LKW Objekt mit Werten füllen
      Caption := intToStr(I);
    end;


    // Werte Inkrementieren
    inc(i);
    If (Links + (myLKWBreite*2) + myLKWAbstand) > sbTouren.Width then
    begin
      Links := myLKWAbstand;
      Inc(Oben, myLKWHoehe + myLKWAbstand);
    end else
    begin
      Inc(Links, myLKWBreite + myLKWAbstand);
    end;
    tblLkw.Next;
  end;
end;
Schleife zum freigeben der Panels - Bei Setlength und bei myLKW := Nil gibts den error
Code:
procedure TfrmTourenplan.LkwPanelsFreigeben;
Var
  max, i: integer;

begin
  IF myLKW <> nil then
  begin
    max := Length(myLKW);
    For I := max Downto 0 do
    begin
      myLKW[i].myDestroy;
      sleep(100);
    end;

    // Hier gibts den Fehler
    SetLength(myLKW, 0);
    // Oder hier wenn die Zeile hierdrüber ausdokumentiert wird
    myLKW := NIL;


  end;
end;

habt Ihr da vielleicht ne Idee?

Danke schonmal, michel

Stevie 26. Nov 2004 12:13

Re: Panels dynamisch erzeugen -> Ungültige Zeigeroperatio
 
Ihhhh, Konstruktor und Destruktor anders nennen, als Create oder Destroy??? :shock:
Sorry, aber das musste raus! :lol:

Versuch das ganze lieber über ne TList, als über dieses Array-Gedöns. :wink:

Luckie 26. Nov 2004 12:27

Re: Panels dynamisch erzeugen -> Ungültige Zeigeroperatio
 
Nenn den Destruktor Destroy und rufe zum Freigeben die Methode Free von TObjekt auf.

Sprint 26. Nov 2004 12:36

Re: Panels dynamisch erzeugen -> Ungültige Zeigeroperatio
 
Ein kleiner Hinweis, wenn wir uns schon beim objekt-orientierten Programmieren befinden:
Zitat:

Code:
var
  myLKW : Array OF TMyLKWObjekt;

Benutze TObjectList.

Taweluki 26. Nov 2004 13:10

Re: Panels dynamisch erzeugen -> Ungültige Zeigeroperatio
 
TObjectList ist die beste Wahl, sonst macht man noch Fehler wie den folgenden:

Zitat:

Zitat von mika
Code:
    max := Length(myLKW);
    For I := max Downto 0 do
    begin
      myLKW[i].myDestroy;
      sleep(100);
    end;

Length() liefert die Anzahl der Elemente, diese ist bei offenen Arrays aber um eins größer als der höchste zulässige Index (anders als bei den mit Index 1 beginnenden Strings, wo Length den Index des letzten Zeichens liefert). Mit myLKW[Lenght(myLKW)] greifst du fröhlich auf uninitialisierten bzw. ungültigen Speicher zu. Ersetze Length(myLKW) durch High(myLKW) und gut ist.

Und die Variable max kannst du dir eigentlich auch sparen, der Compiler optimiert die höchstwahrscheinlich sowieso weg. for i := High() downto 0 do... ist besser lesbar als for i := max downto 0 do..., weil man nicht erst nachsehen muss, was "max" eigentlich ist. Gilt natürlich nicht, wenn die Berechnung von max kompliziert ist oder max öfter als einmal benötigt wird.

mika 26. Nov 2004 14:29

Re: Panels dynamisch erzeugen -> Ungültige Zeigeroperatio
 
Aloa an alle und danke für eure Antworten :)



Zitat:

Zitat von Stevie
Ihhhh, Konstruktor und Destruktor anders nennen, als Create oder Destroy???

die heissen ja auch MYcreate und MYdestroy :)



Zitat:

Zitat von Luckie
Nenn den Destruktor Destroy und rufe zum Freigeben die Methode Free von TObjekt auf.

probier ich gleich mal aus.

Zitat:

Zitat von Sprint
Ein kleiner Hinweis, wenn wir uns schon beim objekt-orientierten Programmieren befinden:
Zitat:

Code:
var
  myLKW : Array OF TMyLKWObjekt;

Benutze TObjectList.

kenn ich leider nicht :)

Zitat:

Zitat von Taweluki
TObjectList ist die beste Wahl, sonst macht man noch Fehler wie den folgenden:

Length() liefert die Anzahl der Elemente, diese ist bei offenen Arrays aber um eins größer als der höchste zulässige Index (anders als bei den mit Index 1 beginnenden Strings, wo Length den Index des letzten Zeichens liefert). Mit myLKW[Lenght(myLKW)] greifst du fröhlich auf uninitialisierten bzw. ungültigen Speicher zu. Ersetze Length(myLKW) durch High(myLKW) und gut ist.

Ja aber wenn ich High nehme dann hat er im fenster das vorletzte element des arrays gelöscht.
was ich auch recht seltsam fand. Ich war an der Stelle grade am testen da ich den gesagten fehler bekomme... aber ich probier das gleich mal aus und meld mich dann nachher hier wieder.

michel


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