Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Programmzustand speichern und laden (https://www.delphipraxis.net/2024-programmzustand-speichern-und-laden.html)

Madeleine 3. Jan 2003 15:42


Programmzustand speichern und laden
 
Hi,
hab da natürlich mal wieder ne Frage und zwar...
Was würdet ihr empfehlen, um einen bestimmten Zustand eines Programms (z.b.: einen Spielzustand 8) ) zu speichern und dann auch wieder laden zu können. Ich habe etwas von INI-Dateien gehört, was haltet ihr davon und vielleicht könnt ihr mir auch ein paar Tips geben!

Dann schonma Danke im Voraus! :D

Sebastian Nintemann 3. Jan 2003 15:56

Hallo Madeleine, da würde ich dir tatsächlich zu einer INI Datei raten. Die sind recht einfach zu handhaben. Gehe ich richtig davon aus, dass du den Spielstand aus deinem "4 gewinnt" Spiel speichern willst? Wenn ja sollten für dich die Methoden TIniFile.WriteInteger und TIniFile.ReadInteger besonders interessant sein, da du den Zustand eines Spielfeldes ja als Integer speicherst. Guck dir diese Methoden, und TIniFile allgemein doch mal in der Delphi OH an, wenn du Fragen hast schreib ich dir auch gerne (ich bin sicher die anderen auch :wink: ) ein Beispiel.

Gruß, Sebastian

Madeleine 3. Jan 2003 19:29

naja.. :roll: ein kleines beispielchen wär schon nicht schlecht! :spin:
Da ich ja ein DrawGrid oder StringGrid verwende, gibt es da noch etwas zu beachten?
Gruß Madeleine

sakura 3. Jan 2003 20:05

Werte speichern
Delphi-Quellcode:
procedure TfrmMaim.SaveValues;
begin
  with TIniFile.Create('game.ini') do
  try
    WriteString('info', 'Letzter Spieler', FLastPlayer);
    WriteInteger('highscore', 'Beste Punktzahl', FHighScore);
  finally
    Free;
  end;
end;
Werte laden
Delphi-Quellcode:
procedure TfrmMaim.LoadValues;
begin
  with TIniFile.Create('game.ini') do
  try
    FLastPlayer := ReadString('info', 'Letzter Spieler', '');
    FHighScore := ReadInteger('highscore', 'Beste Punktzahl', 0);
  finally
    Free;
  end;
end;

Madeleine 3. Jan 2003 21:09

das habe ich schon so ungefähr verstanden, aber mir ist immer noch keine Idee gekommen, wie man das mit einem zweidimensionalen und auch noch dynamischen Array macht!
Geht das überhaupt?

thx

Tpercon 3. Jan 2003 21:15

Ganz einfach: In zwei Schlüsseln speicherst du die Größe des Arrays.
Dann brauchst du noch für jede Zelle nen Schlüssel und das ganze einfach über zwei Schleifen in die Ini speichern.

Gruß

phlux 3. Jan 2003 21:17

Hi!
Das ganze einfach in einem Stream speichern
Delphi-Quellcode:

//Für {ArrayTyp} setzt du den Array ein den du nutzt

procedure SaveArrayToStream(Array: {ArrayTyp});
var f: TFileStream;//Der Stream in dem wir das ganze speichern

begin
  try
    //Zuerst gucken ob es schon diese Datei gibt, Dateiname kann ja frei gewählt werden
    f := TFileStream.Create('C:\MeinArray.dat', fmOpenReadWrite);
  except
    //Wenn nein, erzeugen wir ihn schnell
    f := TFileStream.Create('C:\MeinArray.dat', fmCreate);
  end;
    //Der Prozedur übergebene "Array" wird in den Stream gespeichert
  f.WriteBuffer(Array, SizeOf(Array));
    //Der FileStream wird freigegeben
  f.Free;
end;
Code ohne gewähr, hab ihn nicht getestet, dürfte aber vom Theoretischen her funzen :)

Madeleine 4. Jan 2003 20:40

ok, danke, aber wie programmiert das ganze so, das man auch die Möglichkeit hat, mehrere Dateien zu speichern, das geht bei mir nämlich noch nicht!?!

nailor 4. Jan 2003 20:47

Du kannst doch den Dateinamen frei wählen. Wenn du dann das ganze mehrmals machst, und verschiedene Dateinamen wählst, dann werden auch verschiedene (also mehrere) Dateien gemacht.

Madeleine 4. Jan 2003 21:17

Liste der Anhänge anzeigen (Anzahl: 1)
na das ist es ja, ich gebe dem einen anderen Namen, rufe ich dann die alte Datei auf mit dem alten Namen, ist das neue dort eingespeichert!
...ganz komisch... :?
Hab mal mein Spiel angehängt, falls es jmd ausprobieren will
in Unit1 steht der Code dazu (ganz unten)
..ich werde mal weiter grübeln...

nailor 4. Jan 2003 21:52

Du speicherst unabhängig von der Eingabe im "speichern unter"-Dialog in die game.ini. Speicher statt in game.ini in die Datei "savedialog1.filename"
Dann speichert er in die Datei, die du dort angibst!
Beim Laden genauso!

trebormillenium 4. Jan 2003 22:25

Für ganz doofe :-)

Also angenommen ich will eine URL speichern und dann später wieder laden! (steht z.Z. in einem Edit Feld)

Wie geht das?

Mit Beispiel wäre schön :D

RomanK 4. Jan 2003 22:55

Hoi,

Zitat:

Für ganz doofe
Ganz doof können die ja nicht sein, immerhin haben sie's bis in das Forum geschaft :mrgreen:
Zum Problem:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  with TIniFile.Create('game.ini') do
  try
    WriteString('URL', 'Letzter url', edit1.Text);
    finally
    Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 with TIniFile.Create('game.ini') do
  try
    edit1.Text := ReadString('URL', 'Letzter url', '');
    finally
    Free;
  end;
end;
und bei uses IniFiles nich vergessen:

Delphi-Quellcode:
uses
  ..., IniFiles;

nailor 4. Jan 2003 23:12

und beim speichern:

Delphi-Quellcode:
if savedialog1.execute then begin
  with TIniFile.Create(savedialog1.filename) do
    try
      //alles dein Zeug, zB
      WriteBool('Optionen', 'Computer', 'die variable, die angibt, ob gegen Computer oder Mensch gespielt wird');
    finally
      Free;
    end;
end;
[Edit=FuckRacism]aus " wird ' :zwinker: [/Edit]

RomanK 4. Jan 2003 23:21

Jo aber eine String bitte in ' und nicht in "
aus:
Delphi-Quellcode:
if savedialog1.execute then begin
  with TIniFile.Create(savedialog1.filename) do
    try
      //alles dein Zeug, zB
      WriteBool('Optionen', 'Computer', "die variable, die angibt, ob gegen Computer oder Mensch gespielt wird");
    finally
      Free;
    end;
end;
wird
Delphi-Quellcode:
if savedialog1.execute then begin
  with TIniFile.Create(savedialog1.filename) do
    try
      //alles dein Zeug, zB
      WriteBool('Optionen', 'Computer', [color=#e50000]'[/color]die variable, die angibt, ob gegen Computer oder Mensch gespielt wird[color=#f60000]'[/color]);
    finally
      Free;
    end;
end;
PS: Ich bin mal so frei und korrigiere das in deinem Post.

trebormillenium 4. Jan 2003 23:24

Hej danke! das klappt sogar! Vielen Dank :lol:

Madeleine 5. Jan 2003 00:12

ok, hiermit oute ich mich mal als dumm,
ich hab immer noch nicht verstanden, was ich falsch gemacht habe und warum es nicht klappt! Erklärts doch bitte nochmal so, das es auch Mädchen verstehen! :mrgreen:

nailor 5. Jan 2003 00:13

Dir ist klar, dass das aber grade KEIN String sein soll. Es soll ein ein Boolean sein. Ist so eine Art Kommentar. Aber auch kein echter Kommentar, weil hinterher ja etwas dafür hin muss. Sollte "Hier muss jetzt das einegfügt werden" heissen.

...Ich liebe diese rekursiven Erklärungen.

Wir können ja mal ein Zeichen zur Markierung von sowas ausmachen. Vielleicht "µ"? Nach der neuen Regel dann µµµ. 8)

PS: Jedenfalls klappt es!

trebormillenium 5. Jan 2003 00:35

Naja da ich es ja jetzt (hoff ich) verstanden habe erkläre ichs dir!

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
// hier erstellt der die *.ini File wo das Programm alles drin speichert
  with TIniFile.Create('game.ini') do
  try
// hier speichert er den Text der im edit-Feld steht also der erstellt eine überschrift URL und dann einen eintrag mit Letzter url! Und dahinter schreibt er dann den text des edit feldes! sieht dann so aus
// Hier ist der Eintrag in der ini-file
[URL]
Letzter url=http://www.delphipraxis.net
__________________________________________________
    WriteString('URL', 'Letzter url', edit1.Text);
    finally
    Free;
  end;
end;

//hier liest er dann die ini-datei aus!
procedure TForm1.Button2Click(Sender: TObject);
begin
with TIniFile.Create('game.ini') do
  try
//hier sucht er sich die "überschrift" URL und den "Eintrag" letzter url, und schreibt die dann in das edit feld!
    edit1.Text := ReadString('URL', 'Letzter url', '');
    finally
    Free;
  end;
end;
So hoffe du hasts vestanden und ich hoffe das ichs richtig erklärt habe :-) Gehe jetzt penne bis morgen!

PS: fast vergeßen :-)

Noch bei "uses" noch "inifiles" hizuschreiben!

Dann noch viel Spass und bis "morgen"!! :thuimb:

Madeleine 5. Jan 2003 00:46

Ich bin scheinbar wirklich zu dumm, habe 'game.ini' in 'savedialog.filenname' geändert....hoffentlich war es das, was ihr gemeint habt und das dumme Ding speichert trotzdem nur ein Spiel!!! :evil: gibt es irgendwas bei diesem Savedialog und Opendialog -Zeug zu beachten???

nailor 5. Jan 2003 00:46

wobei sich hier

edit1.Text := ReadString('URL', 'Letzter url', '');

als dritter Wert (Standard (mit DDD)) vielleicht 'about:blank' nicht schlecht machen würde.
Ihr Problem dabei ist doch, dass sie so nur genau ein Spiel speichern kann, weill der Dateiname ja schon feststeht!

RomanK 5. Jan 2003 00:52

Hast du die ' ' weggemacht ???
Weil "Werte" ('game.ini') werden in Anführungszeichen geschrieben, Variablen (savedialog.filename) die "Werte" beinhalten ohne. ( In savedialog.filename steht der Name des files das du ausgewählt hast)

Madeleine 5. Jan 2003 00:57

*seufz* das klang wie ne richtig gute Idee, aber das wars auch nicht!
:cry: *schnief*

RomanK 5. Jan 2003 01:00

Poste doch mal bitte den Gesamten code

Madeleine 5. Jan 2003 01:08

ich hab mein Spiel mit Code als Anhang in irgendeinem Post weiter vorne
Delphi-Quellcode:
procedure TFrmMain.Save;
var i,n:Integer;
 begin  with TIniFile.Create(savedialog1.filename) do
 try
        if Feldbreite>= FeldHoehe then begin
                For i:=0 to FeldBreite-1 do
                        For n:=0 to FeldHoehe-1 do
                                WriteInteger(IntToStr(i), IntToStr(n), feld[i,n]);
         end
         else begin
                For i:=0 to FeldHoehe-1 do
                        For n:=0 to FeldBreite-1 do
                                WriteInteger(IntToStr(i), IntToStr(n), feld[i,n]);
         end;
        WriteInteger('Infos','Letzter Spieler',spieler);
        WriteInteger('Feld','Feldhöhe',FeldHoehe);
        WriteInteger('Feld','Feldbreite',FeldBreite);
        WriteBool('Infos','Computergegner',Computergegner);
  finally    Free;
  end;
  end;
procedure TFrmMain.Load;
var i,n:Integer;
begin with TIniFile.Create(savedialog1.filename) do
try
        spieler := ReadInteger('Infos', 'Letzter Spieler',spieler);
        FeldHoehe:= ReadInteger('Feld','Feldhöhe',FeldHoehe);
        FeldBreite:= ReadInteger('Feld','Feldbreite',FeldBreite);
        Computergegner:= ReadBool('Infos','Computergegner',Computergegner);
        if FeldBreite>=Feldhoehe then begin //um sicher zu stellen, das wenn Feldbreite kleiner als hoehe ist, Schleife nicht zu früh abbricht
                For i:=0 to FeldBreite-1 do
                        For n:=0 to FeldHoehe-1 do
                                feld[i,n]:= ReadInteger(IntToStr(i),IntToStr(n),Feld[i,n]);
        end
        else begin For i:=0 to Feldhoehe-1 do
                        For n:=0 to Feldbreite-1 do
                                feld[i,n]:= ReadInteger(IntToStr(i),IntToStr(n),Feld[n,i]);
        end;
        StringGrid.RowCount:=FeldHoehe+1;
        StringGrid.ColCount:=FeldBreite;
        Stringgrid.Width:=Stringgrid.ColCount*41+3;
        Stringgrid.Height:=Stringgrid.RowCount*41+3;
        FrmMain.Height:=Stringgrid.Height+40;
        FrmMain.Width:=Stringgrid.Width;
finally    Free;
 end;
 end;

procedure TFrmMain.Speichern1Click(Sender: TObject);
begin
if SaveDialog1.Execute then Save
end;

procedure TFrmMain.Laden1Click(Sender: TObject);
var i,n:Integer;
begin
if OpenDialog1.Execute then Load;

end;

Christian Seehase 5. Jan 2003 01:21

Moin Madeleine,

Du verwendest in der Procedure Load auch den SaveDialog1.FileName, obwohl Du bei erfolgreichem OpenDialog1.Execute Load aufrufst.

Madeleine 5. Jan 2003 01:35

oh :oops: und das beste ist, du hast recht, jetzt klappt alles nach Wunsch!!! :hello:
Danke! :party:

trebormillenium 5. Jan 2003 20:32

Hallo
ich schon wieder :-)
Habe nochmal Probleme mit dem speichern
Was ist wenn ich keinen String sonder einen TString speichern will?
Ich kriegs net hin!

phlux 5. Jan 2003 20:35

Haben TStrings nicht die Prozedur SaveToFile?

trebormillenium 5. Jan 2003 20:48

Aha so und jetzt das es ein blutiger anfänger auch versteht :-) Am besten mit Source-Code!

Schonmal vielen Dank!

phlux 6. Jan 2003 08:57

Okay hier mal ne kleine Prozedur:
Delphi-Quellcode:
//Beispiel für TStringList
var f: TStringlist;

procedure SaveStringList;
begin
  f := TStringList.Create;//Erstellt Stringlist
  f.Add('Ein String');//Fügt einen String hinzu
  f.SaveToFile('C:\MeineStrings.txt');
  f.Free;
end;

procedure LoadStringList;
begin
  f := TStringList.Create;//Erstellt Stringlist
  f.LoadFromFile('C:\MeineStrings.txt');
end;
Eigentlich ist es komfortabler TStringList zu nehmen anstatt TStrings.

Christian Seehase 6. Jan 2003 13:45

Moin Phlux,

von TStrings sollte man tunlichst keine Instanzen bilden, da TStrings eine abstrakte Klasse darstellt.
Bei einer abstrakten Klasse ist mindestens eine Methode nur deklariert, aber nicht "mit Leben gefüllt", so dass ein Zugriff auf diese Methode in einer Access Violation mündet. (wie wohl z.B. LoadFromFile/SaveToFile, wenn ich mich recht entsinne).

Eine Klasse, die diese abstrakten Methoden von TStrings implementiert wäre TStringList.

Als Typ für einen Funktionsparameter wäre es allerdings wiederum von Vorteil TStrings zu verwenden, da man dann alle Nachfahren von TStrings als Parameter übergeben kann, also z.B. Memo1.Lines ebenso wie eine Variable vom Typ TStringList.

phlux 6. Jan 2003 14:05

uuups.. :oops: Danke das du mich auf diesen Fehler hingewiesen hast. Das nächste mal poste ich nich mehr so früh :lol:

Christian Seehase 6. Jan 2003 14:16

Moin Phlux,

es war ja nur der Typ nicht ganz richtig.
Du hättest nur TStrings durch TStringList ersetzen müssen, dann hätte es ja funktioniert.

phlux 6. Jan 2003 14:23

Jo aber er hat ja eh explizit nach TStrings gefragt. Werd den code aber heut abend wieder reinstellen.

trebormillenium 7. Jan 2003 20:17

:?
Was ist mit der Prozedur? Habe ein ComboBox genommen und will dort eine Internet-Adresse eigeben, dann die adresse in die Tstring liste aufnehmen lassen und abspeichern lassen!

Hoffe ihr könnt mir helfen!

phlux 7. Jan 2003 20:23

Delphi-Quellcode:
//speichern
  ComboBox1.Items.SaveToFile('C:\Strings.txt');

//laden
  ComboBox1.Items.LoadFromFile('C:\Strings.txt');

//Dateiname is frei wählbar ersetze einfach C:\Strings.txt

Sibbe05 29. Jan 2003 10:10

Ich habe mal 'ne Frage:
Ich möchte eine .ini datei öffnen (Mit opendialog),
das programm soll dann eine .ini datei erzeugen, falls die datei mit eingegebenen namen nicht vorhanden ist.
Wenn ich nun einen beliebigen namen eingebe, erstellt er mir keine
neue .ini datei, sondern füllt alles mit den default werten.
Warum???

Christian Seehase 29. Jan 2003 13:36

Moin Sibbe,

ich hab' jetzt Dein Problem nicht ganz verstanden, könntest Du das bitten noch mal etwas genauer beschreiben?

Sibbe05 29. Jan 2003 14:42

hat sich schon geklärt...
Trotzdem danke.

-------
Sibbe05


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:32 Uhr.
Seite 1 von 2  1 2      

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