Entwickler-Ecke

Sonstiges (Delphi) - Globale Variablen definieren


Nemo - Fr 11.03.05 10:35
Titel: Globale Variablen definieren
Guten Morgen Forumisten und Forumistinnen!

Ich will gleich zum Problem kommen:

Ich habe am Anfang der Pas Datei einige "Globale" Variablen definiert und gleich zugewiesen. Einige Strings unt Integerwerte für den Programmablauf und einige Arrays aus Strings und TBitmaps.
Früher funktionierte das Programm einfachheitshalber so:
Programm start, Variablen werden gesetzt.
Programm wird ausgeführt.
Programm wird beendet.


Jetzt aber soll man nach dem Beenden das Programm ein zweites mal ausführen können (ohne Neustart desselbigen), also muss alles wieder auf Anfang. Mit den Strings und Integers kein Problem ich setze sie beim zweiten mal auf Ihre Originalwerte zurück. Aber die arrays, speziell der TBitmap macht mir etwas Sorgen. Wie bekomme ich den wieder auf Ausgangswert (PreviewBilder: Array [0..999] of TBitmap;)


Gruss, Euer Nemo.


Lossy eX - Fr 11.03.05 11:02

Ich kann dir gerade nicht folgen. Wie schafst du es ein Programm zu beenden und wieder zu starten ohne es neu zu starten?

Neustartet bezeichnet ja nichts anderes als es zu beenden und wieder zu starten. Wenn du das tust, dann sind ja Werte wieder auf ihrem Uhrsprungswert. Und das ist ja doch genau das was du willst, oder?

PS: Ich halte globale Variablen nur in sehr wenigen Fällen für sinnvoll, da sie oftmals die Flexibilität behindern und es einfach viel schöner ist, wenn sie Bestandteil einer Klasse sind. Aber das nur mal am Rande.


Nemo - Fr 11.03.05 11:32

Neustarten: Programm mit dem X oder Form.Close schließen.

Was ich will: Knopf im Programm Namens "Nochmal machen". Hierbei wird die Form nicht geschlossen und es kommt auch zu keiner neudefinierung der Variablen. Am schlimmsten ist dabei der TBitmap Array. Eine meiner Routinen prüft nämlich ob er leer ist oder nicht. Also wie mache ich den wieder leer?

PreviewBilder: array of TBitmap;


Lossy eX - Fr 11.03.05 11:39

Wenn das Array ein Bestandteil des Forms oder einer anderen Klasse wäre könntest du die Klasse wegwerfen und neu erstellen und dann wäre alles wieder so wie im Urzustand. Das ist die sauberste Möglichkeit. Und auch gar nicht mal schwer. Dazu rate ich dir auch!

Die andere Möglichkeit wäre in dem du alle Variablen wieder auf ihren Urzustand setzt. Also Texte zuweise. Ints zuweisen. Und für das Array bräuchtest du eine Schleife.

Delphi-Quelltext
1:
2:
3:
4:
5:
for Idx := low(PreviewBilder) to High(PreviewBilder) do
  if Assigned(PreviewBilder[Idx]) then begin
    PreviewBilder[Idx].Free;
    PreviewBilder[Idx] := nil;
  end;

In der Schleife wird das Bild frei gegeben und auf nil gesetzt.


wdbee - Fr 11.03.05 11:41

Dazu musst du noch prüfen, wem die TBitmap-Objekte gehören.

Variante 1: Sie gehören dem Array, dann muss der sie erst freigeben und dann den Zeiger auf nil setzen.

Variante 2: Sie gehören nicht dem Array, eine andere Stelle im Programm hat die TBitmap-Objekte schon freigegeben, dann wir nur der Zeiger auf nil gesetzt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  I: Integer;
  TheArray: array [X..Y] of TBitmap;
  ABitmap: TBitMap;
  ...
  for I := Low(TheArray) to High(TheArray)
  begin
    ABitmap := TheArray[I];   // Nur bei Variante 1
    ABitmap.Free;             // Nur bei Variante 1
    TheArray[I] := nil;       // Bei Variante 1 und 2
  end;


@Losssi eX: Die Assigned-Prüfung ist nicht nötig, denn das macht Free selbst auch. Wäre also nur doppelt gemoppelt.


Nemo - Fr 11.03.05 12:00

wdbees Variante scheint zu funktionieren, wenn auch immernoch ein Hund drin ist. Der hat aber vermutlich mit dem String Array zu tun, der noch immer die Bildpfade enthält. Ich werde mal versuchen die Arrays of String auf ähnliche Weise zu löschen...

Da fällt mir ein, nil ist ein Pointer. Welchen Wert haben leere Strings und Integer eigentlich?


Lossy eX - Fr 11.03.05 12:05

user profile iconwdbee hat folgendes geschrieben:
@Lossy eX: Die Assigned-Prüfung ist nicht nötig, denn das macht Free selbst auch. Wäre also nur doppelt gemoppelt.


Ich weiß. Eigentlich braucht man das nicht. Ich habe mir aber angewöhnt überall zu überprüfen ob es gültig ist, wenn ich mit Objekten arbeite die Nil sein können. Da teilweise austragen aus Listen etc noch dabei ist.

PS: Das Temporäre Bitmap kannst du dir sparen, da es ja nur ein Pointer auf das selbe Objekt ist.

@nemo:
Integer haben 0 als wert und Strings einen Leeren String.

Delphi-Quelltext
1:
Leerstring := '';                    


Nemo - Fr 11.03.05 14:03

user profile iconLossy eX hat folgendes geschrieben:
@nemo:
Integer haben 0 als wert und Strings einen Leeren String.


Gut, so hab ichs inzwischen auch gemacht und funktioniert nun ganz tadellos. Danke Euch beiden für die Hilfe!


wdbee - Fr 11.03.05 15:31

@Lossi eX:
Im Prinzip richtig. Aber ich mache das immer so, damit ich bei einer Fehlersuche einen Breakpoint setzen und mit der Maus kontrollieren kann, was das für ein Objekt ist, ohne den Quellcode ändern zu müssen. Außer bei Free und in privaten Methoden ist es natürlich richtig auf nil gefasst zu sein.