![]() |
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 |
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 |
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 |
Werte speichern
Delphi-Quellcode:
Werte laden
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;
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; |
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 |
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ß |
Hi!
Das ganze einfach in einem Stream speichern
Delphi-Quellcode:
Code ohne gewähr, hab ihn nicht getestet, dürfte aber vom Theoretischen her funzen :)//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; |
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!?!
|
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.
|
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... |
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! |
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 |
Hoi,
Zitat:
Zum Problem:
Delphi-Quellcode:
und bei uses IniFiles nich vergessen:
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;
Delphi-Quellcode:
uses
..., IniFiles; |
und beim speichern:
Delphi-Quellcode:
[Edit=FuckRacism]aus " wird ' :zwinker: [/Edit]
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; |
Jo aber eine String bitte in ' und nicht in "
aus:
Delphi-Quellcode:
wird
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;
Delphi-Quellcode:
PS: Ich bin mal so frei und korrigiere das in deinem Post.
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; |
Hej danke! das klappt sogar! Vielen Dank :lol:
|
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: |
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! |
Naja da ich es ja jetzt (hoff ich) verstanden habe erkläre ichs dir!
Delphi-Quellcode:
So hoffe du hasts vestanden und ich hoffe das ichs richtig erklärt habe :-) Gehe jetzt penne bis morgen!
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; PS: fast vergeßen :-) Noch bei "uses" noch "inifiles" hizuschreiben! Dann noch viel Spass und bis "morgen"!! :thuimb: |
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???
|
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! |
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) |
*seufz* das klang wie ne richtig gute Idee, aber das wars auch nicht!
:cry: *schnief* |
Poste doch mal bitte den Gesamten code
|
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; |
Moin Madeleine,
Du verwendest in der Procedure Load auch den SaveDialog1.FileName, obwohl Du bei erfolgreichem OpenDialog1.Execute Load aufrufst. |
oh :oops: und das beste ist, du hast recht, jetzt klappt alles nach Wunsch!!! :hello:
Danke! :party: |
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! |
Haben TStrings nicht die Prozedur SaveToFile?
|
Aha so und jetzt das es ein blutiger anfänger auch versteht :-) Am besten mit Source-Code!
Schonmal vielen Dank! |
Okay hier mal ne kleine Prozedur:
Delphi-Quellcode:
Eigentlich ist es komfortabler TStringList zu nehmen anstatt TStrings.
//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; |
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. |
uuups.. :oops: Danke das du mich auf diesen Fehler hingewiesen hast. Das nächste mal poste ich nich mehr so früh :lol:
|
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. |
Jo aber er hat ja eh explizit nach TStrings gefragt. Werd den code aber heut abend wieder reinstellen.
|
:?
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! |
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 |
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??? |
Moin Sibbe,
ich hab' jetzt Dein Problem nicht ganz verstanden, könntest Du das bitten noch mal etwas genauer beschreiben? |
hat sich schon geklärt...
Trotzdem danke. ------- Sibbe05 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz