Button lässt Programm abstürzen
lima-city → Forum → Programmiersprachen → Delphi & Pascal
array
button
byte
code
datei
dialog
einlesen
erstellen
format
history
implementation
index
login
not
record
sender
statuszeile
string
text
type
-
Hey, ich schreibe an einem Projekt.
Der Button LOGIN soll momentan nur einen Usernamen einlesen, mit einer Datei vergleichen und wenn vorhanden, einen dazugehörigen Chatverlauf laden und wenn nicht, einen neuen anlegen und den User in einer Datei speichern.
Wenn ich den Button drücke läuft alles gut, aber wenn ich es ein weiteres Mal tue, egal ob das Prog zwischendurch beendet wurde... wenn die Users.dat existiert stürzt dsa Prog ab, wenn der Button gedrückt wird. Auch vor dem Einlesen der Datei, wo eine Statuszeile beschriftet werden soll, schon. Hier der Code der Hauptunit und der Auslagerung...
Ich benutze Delphi 7 EE.
mfg eS
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uHelp, ComCtrls; //================================= //MEMO FENSTER ALS STATUSZEILE EINRICHTEN!!! //================================= type TForm1 = class(TForm) grpbxLogin: TGroupBox; Label1: TLabel; edtName: TEdit; Label2: TLabel; edtPass: TEdit; btnLogin: TButton; btnLogout: TButton; grpbxChat: TGroupBox; mmChat: TMemo; edtChat: TEdit; btnChat: TButton; stsbrStatus: TStatusBar; procedure FormCreate(Sender: TObject); procedure btnLoginClick(Sender: TObject); procedure btnLogoutClick(Sender: TObject); private { Private-Deklarationen} public { Public-Deklarationen} end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin stsbrStatus.Panels[0].Text := 'Loading...'; ASSIGNFILE(TempLoginBank, LoginBank); btnLogout.Enabled := FALSE; grpbxChat.Enabled := FALSE; btnLogin.Default := True; stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'Welcome!' + #13#10; end; procedure TForm1.btnLoginClick(Sender: TObject); var Name, Pass : STRING; Logins : ARRAY[1..255] OF TLogin; INDEX : BYTE; INDEX2 : BYTE; Gefunden : BOOLEAN; begin stsbrStatus.Panels[0].Text := 'Reading Logins...'; LoginOeffnen; // LoginDatenbank Einlesen Seek(TempLoginBank, 0); // . INDEX := 0; // . WHILE NOT(EOF(TempLoginBank)) DO // . begin // . INC(INDEX); // . Read(TempLoginBank, Logins[INDEX]); // . end; // . CloseFile(TempLoginBank); // _______________________ stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'Logins red...' + #13#10; Name := edtName.Text; Pass := edtPass.Text; Login.Name := Name; Login.Pass := Pass; ChatFile := Name + '.dat'; ASSIGNFILE(TempChatFile, ChatFile); Gefunden := FALSE; stsbrStatus.Panels[0].Text := 'Checking Login...'; FOR INDEX2 := 1 TO INDEX+1 DO IF Login.Name = Logins[INDEX2].Name THEN Gefunden := TRUE; IF Gefunden THEN begin mmChat.Text := mmChat.Text + 'Logged in...' + #13#10; stsbrStatus.Panels[0].Text := 'Loading Chat...'; ChatOeffnen; //Chat einlesen und darstellen! Seek(TempChatFile, 0); INDEX := 0; WHILE NOT(EOF(TempChatFile)) DO begin INC(INDEX); Read(TempChatFile, Chat[INDEX]); end; CloseFile(TempChatFile); stsbrStatus.Panels[0].Text := 'Displaying Chat'; FOR INDEX2 := 1 TO INDEX DO mmChat.Text := mmChat.Text + '[' + IntToStr(Chat[INDEX2].Day) + '.' + IntToStr(Chat[INDEX2].Month) + '.' + IntToStr(Chat[INDEX2].Year) + '-' + IntToStr(Chat[INDEX2].Hour) + ':' + IntToStr(Chat[INDEX2].Minute) + ':' + IntToStr(Chat[INDEX2].Second) + ' - '+ Chat[INDEX2].Sender + ']' + ' ' + Chat[INDEX2].Content + #13#10; stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'Chat History loaded...' + #13#10; end ELSE //Neue ChatDatei erstellen!, Login Saven! begin stsbrStatus.Panels[0].Text := 'Prep new Chat'; ChatOeffnen; CloseFile(TempChatFile); mmChat.Text := mmChat.Text + 'New Chat History prepared...' + #13#10; stsbrStatus.Panels[0].Text := 'Saving Login...'; LoginOeffnen; INDEX := 0; Seek(TempLoginBank, 0); WHILE NOT(EOF(TempLoginBank)) DO INC(INDEX); Logins[INDEX + 1] := Login; FOR INDEX2 := 1 TO INDEX+1 DO Write(TempLoginBank, Logins[INDEX]); CloseFile(TempLoginBank); stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'User saved...' + #13#10; end; btnLogin.Default := FALSE; grpbxLogin.Enabled := FALSE; btnLogout.Enabled := TRUE; grpbxChat.Enabled := TRUE; edtChat.SetFocus(); btnChat.Default := TRUE; end; procedure TForm1.btnLogoutClick(Sender: TObject); begin mmChat.Text := 'Welcome' + #13#10; btnLogout.Enabled := FALSE; grpbxChat.Enabled := FALSE; grpbxLogin.Enabled := TRUE; btnLogin.Default := True; end; end.
unit uHelp; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; PROCEDURE LoginOeffnen(); PROCEDURE ChatOeffnen(); TYPE TMessage = RECORD Content, Sender : STRING[128]; Year : INTEGER; Month : BYTE; Day : BYTE; Hour : BYTE; Minute : BYTE; Second : BYTE; end; TLogin = RECORD Name : STRING[128]; Pass : STRING[128]; end; CONST LoginBank = 'Users.dat'; VAR TempLoginBank : FILE OF TLogin; ChatFile : STRING; TempChatFile : FILE OF TMessage; Chat : ARRAY[1..2147483] OF TMessage; Login : TLogin; implementation PROCEDURE LoginOeffnen(); begin IF FileExists(LoginBank) THEN RESET(TempLoginBank) ELSE begin REWRITE(TempLoginBank); end; IF NOT(FileExists(LoginBank)) THEN ShowMessage('Fehler beim Erstellen der Datei!'); end; PROCEDURE ChatOeffnen(); begin IF FileExists(ChatFile) THEN RESET(TempChatFile) ELSE begin REWRITE(TempChatFile); end; IF NOT(FileExists(ChatFile)) THEN ShowMessage('Fehler beim Erstellen der Datei!'); end; end.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
PROCEDURE LoginOeffnen(); begin IF FileExists(LoginBank) THEN RESET(TempLoginBank) ELSE begin REWRITE(TempLoginBank); end; IF NOT(FileExists(LoginBank)) THEN ShowMessage('Fehler beim Erstellen der Datei!'); end;
Wenn ich das richtig interpretiere, dann erzeugst du mit REWRITE(TempLoginBank) die "user.dat", falls diese nicht existiert, oder?
Es wird aber kein Record in die "user.dat" eingetragen.
Logins : ARRAY[1..255] OF TLogin;
In Pascal begint der erste Datensatz immer mit Null, deshalb lasse besser das array Logins mit 0 beginnen.
ändere dann:
WHILE NOT(EOF(TempLoginBank)) DO // . begin // . INC(INDEX); // . Read(TempLoginBank, Logins[INDEX]); // . end;
in:
WHILE NOT(EOF(TempLoginBank)) DO // . begin // . Read(TempLoginBank, Logins[INDEX]); // . INC(INDEX); // . end;
Das Aufhängen deines Progs geschieht in der while-Schleife.
-
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uHelp, ComCtrls; //================================= //MEMO FENSTER ALS STATUSZEILE EINRICHTEN!!! //================================= type TForm1 = class(TForm) grpbxLogin: TGroupBox; Label1: TLabel; edtName: TEdit; Label2: TLabel; edtPass: TEdit; btnLogin: TButton; btnLogout: TButton; grpbxChat: TGroupBox; mmChat: TMemo; edtChat: TEdit; btnChat: TButton; stsbrStatus: TStatusBar; procedure FormCreate(Sender: TObject); procedure btnLoginClick(Sender: TObject); procedure btnLogoutClick(Sender: TObject); private { Private-Deklarationen} public { Public-Deklarationen} end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin stsbrStatus.Panels[0].Text := 'Loading...'; ASSIGNFILE(TempLoginBank, LoginBank); btnLogout.Enabled := FALSE; grpbxChat.Enabled := FALSE; btnLogin.Default := True; stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'Welcome!' + #13#10; end; procedure TForm1.btnLoginClick(Sender: TObject); var Name, Pass : STRING; Logins : ARRAY[0..255] OF TLogin; INDEX : BYTE; INDEX2 : BYTE; Gefunden : BOOLEAN; HelloChatMessage : TMessage; begin Time; HelloChatMessage.DateTime := DateTime; HelloChatMessage.Sender := 'SYS'; HelloChatMessage.Content := 'Chat started...'; stsbrStatus.Panels[0].Text := 'Reading Logins...'; LoginOeffnen; // LoginDatenbank Einlesen Seek(TempLoginBank, 0); // . INDEX := 0; // . WHILE NOT(EOF(TempLoginBank)) DO // . begin // . Read(TempLoginBank, Logins[INDEX]); // . INC(INDEX); // . end; // . CloseFile(TempLoginBank); // _______________________ stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'Logins red...' + #13#10; Name := edtName.Text; Pass := edtPass.Text; Login.Name := Name; Login.Pass := Pass; ChatFile := Name + '.dat'; ASSIGNFILE(TempChatFile, ChatFile); Gefunden := FALSE; stsbrStatus.Panels[0].Text := 'Checking Login...'; FOR INDEX2 := 0 TO INDEX+1 DO IF Login.Name = Logins[INDEX2].Name THEN Gefunden := TRUE; IF Gefunden THEN begin mmChat.Text := mmChat.Text + 'Logged in...' + #13#10; stsbrStatus.Panels[0].Text := 'Loading Chat...'; ChatOeffnen; //Chat einlesen und darstellen! Seek(TempChatFile, 0); INDEX := 0; WHILE NOT(EOF(TempChatFile)) DO begin Read(TempChatFile, Chat[INDEX]); INC(INDEX); end; CloseFile(TempChatFile); stsbrStatus.Panels[0].Text := 'Displaying Chat'; FOR INDEX2 := 0 TO INDEX-1 DO mmChat.Text := mmChat.Text + '[' + Chat[INDEX2].DateTime + ' - ' + Chat[INDEX2].Sender + ']' + ' ' + Chat[INDEX2].Content + #13#10; stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'Chat History loaded...' + #13#10; end ELSE //Neue ChatDatei erstellen!, Login Saven! begin stsbrStatus.Panels[0].Text := 'Prep new Chat'; Chat[0] := HelloChatMessage; ChatOeffnen; Seek(TempChatFile, 0); Write(TempChatFile, Chat[0]); //Eintrag schreiben, um beim Laden nicht abzustürzen CloseFile(TempChatFile); mmChat.Text := mmChat.Text + 'New Chat History prepared...' + #13#10; mmChat.Text := mmChat.Text + '[' + HelloChatMessage.DateTime + ' - ' + HelloChatMessage.Sender + ']' + ' ' + HelloChatMessage.Content + #13#10; stsbrStatus.Panels[0].Text := 'Saving Login...'; LoginOeffnen; INDEX := 0; Seek(TempLoginBank, 0); WHILE NOT(EOF(TempLoginBank)) DO INC(INDEX); Logins[INDEX + 1] := Login; Seek(TempLoginBank, 0); FOR INDEX2 := 0 TO INDEX+1 DO Write(TempLoginBank, Logins[INDEX]); CloseFile(TempLoginBank); stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'User saved...' + #13#10; end; btnLogin.Default := FALSE; grpbxLogin.Enabled := FALSE; btnLogout.Enabled := TRUE; grpbxChat.Enabled := TRUE; edtChat.SetFocus(); btnChat.Default := TRUE; end; procedure TForm1.btnLogoutClick(Sender: TObject); begin mmChat.Text := 'Welcome' + #13#10; btnLogout.Enabled := FALSE; grpbxChat.Enabled := FALSE; grpbxLogin.Enabled := TRUE; btnLogin.Default := True; end; end.
Das ist nun der neue... Ich weiss nicht ob ich dich richtig verstanden habe, jedenfalls läuft es nicht.
Beitrag zuletzt geändert: 24.2.2013 13:52:53 von evilstorys -
ersetze:
evilstorys schrieb:
LoginOeffnen; INDEX := 0; Seek(TempLoginBank, 0); WHILE NOT(EOF(TempLoginBank)) DO INC(INDEX); Logins[INDEX + 1] := Login; Seek(TempLoginBank, 0); FOR INDEX2 := 0 TO INDEX+1 DO Write(TempLoginBank, Logins[INDEX]); CloseFile(TempLoginBank); stsbrStatus.Panels[0].Text := ''; mmChat.Text := mmChat.Text + 'User saved...' + #13#10; end; btnLogin.Default := FALSE; grpbxLogin.Enabled := FALSE; btnLogout.Enabled := TRUE; grpbxChat.Enabled := TRUE; edtChat.SetFocus(); btnChat.Default := TRUE; end;
Das ist nun der neue... Ich weiss nicht ob ich dich richtig verstanden habe, jedenfalls läuft es nicht.
durch
WHILE NOT(EOF(TempLoginBank)) DO Read(TempLoginBank, Logins[INDEX]); // Zeiger auf letzten Datensatz setzen INC(INDEX); //FOR INDEX2 := 1 TO INDEX+1 DO Write(TempLoginBank, Login); // Datensatz anfügen CloseFile(TempLoginBank);
Beitrag zuletzt geändert: 25.2.2013 14:52:19 von gorgon -
.. und übrigens so zur Vermeidung von Schreibarbeit...
PROCEDURE LoginOeffnen();
PROCEDURE ChatOeffnen();
Wenn du keine Parameter der Procedure oder auch Function übergeben willst, kannst du die () weglassen.
INDEX : BYTE;
INDEX2 : BYTE;
Var-Definitionen vom gleichen Typ kannst du auch mit Komma in einer Zeile schreiben: INDEX,INDEX2:byte;
mmChat.Text := 'Welcome' + #13#10;
Hier würde ich in den globalen Definitionen sowas machen: const LF = #13#10;
Danach kannst du dann überall an einen String so schreiben:
mmChat.Text := 'Welcome' + LF;
Alternativ kannst du auch so schreiben:
mmChat.Text := 'Welcome'#13#10; //also ohne + zwischen dem String; nur wenn du die Zeile umbrichst ist ein + nötig.
Für Texte mit vielen Variablen, die eingefügt werden sollen, bietet sich die Funktion FORMAT an:
mmChat.Text := mmChat.Text +
'[' + HelloChatMessage.DateTime + ' - ' +
HelloChatMessage.Sender + ']' + ' ' +
HelloChatMessage.Content + #13#10;
"Einfacher":
mmChat.Text := mmChat.Text+format('%s[%s - %s] %s'+LF, [mmChat.Text,HelloChatMessage.DateTime,HelloChatMessage.Sender,HelloChatMessage.Content]);
// wobei ich gerade nicht weiß, von welchem Typ TMessage.DateTime ist, ggf musst du hier noch den Typ umwandeln in einen String (DateTimeToStr).
Nebenbei: mmChat ist nach deiner Definition ein TMemo. Dieses hat die Procedure ADD.
Nimm also anstelle von .Text lieber:
mmChat.Lines.Add(format.......);
So wird jede Zeile korrekt angefügt und es ist auch für dich einfacher.
So lange Variablen-Namen wie HelloChatMessage kann man auch so verwenden:
with HelloChatMessage do begin DateTime:=now; Sender:='SYS'; Content:='Blabla..'; end;
Und abschließend noch was praktisches in der TMemo-Komponente:
Wenn du den Inhalt des Memo speichern/einlesen willst, dann schreib doch einfach (weil du es ja einfach nur darstellen willst):
mmChat.Lines.SavetoFile('chat-verlauf.txt'); // und irgendwann wieder einlesen mit mmChat.lines.Loadfromfile('chat-verlauf.txt');
Grüße
:)
Beitrag zuletzt geändert: 27.2.2013 1:39:04 von mathesoft -
Die Konstante LF gibt es schon als sLineBreak ;). Das "with" würde ich schnell wieder vergessen, da es einzig der Schreibfaulheit dient und ansonsten eher nachteilig ist (erschwertes Debugging, Verwechslungsgefahren, etc.). Und bitte niemals relative Pfade verwenden, da diese sich auf das aktuelle Arbeitsverzeichnis beziehen, welches aber z.B. durch einen OpenDialog geändert werden kann. Übrigens: wieso verwendest Du ein statisches Array für die Logins? Ein dynamisches Array oder eine TList wären doch viel flexibler.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage