![]() |
Delphi-Version: 2009
Memo lässt Zeilen verschwinden
Hallo!
Ich bin gerade dabei ein Chat-Programm für Dropbox zu entwickeln. Nix großes und manche Stimmen halten es für überflüssig, aber ich finds toll :wink: Hintergrund: Ich arbeite mit einem Verzeichnis in dem x txt-Dateien liegen. Diese lade ich bei einer Aktualisierung in ein array (da das integrierte Datum zum sortieren beutzt wird) vom typ record (Username, Datum/Zeit, Nachricht). Danach wird alles in einem Memo angezeigt. Das Problem ist, dass immer der vorletzte Eintrag (von beispielseise 3 txt-Dateien) nur mit Username und Datum angezigt wird. Die Nachricht ist nicht zu sehen. Das Array läuft sauber, die Daten exisiteren, nur die Darstellung nicht :? Vielleicht hilft es, wenn ich zusätzlich die EXE bereitstelle? Hier ist der Code. Unwichtige Funktionen/Prozeduren habe ich ausgeklammert.
Delphi-Quellcode:
unit main;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ImgList; function RandomString(const len: Integer = 30; const CharSet: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'): string;overload; type TEntry = record User: String[25]; Msg: TStringList; DatumZeit: String; end; TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; BSend: TButton; MOutput: TMemo; MMessage: TMemo; EUser: TEdit; Label1: TLabel; EDiv: TEdit; Label2: TLabel; BSort: TButton; Icons: TImageList; BRefresh: TButton; procedure FormCreate(Sender: TObject); procedure BSendClick(Sender: TObject); procedure BSortClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BRefreshClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; Entry: TEntry; Entries: Array of TEntry; AufAb: Boolean; implementation {$R *.dfm} procedure GetFilesInDirectory(Directory: string; const Mask: string; List: TStrings; WithSubDirs, ClearList: Boolean); [...] end; procedure Sortieren(Aufsteigend: Boolean); var E: TEntry; i, j, max: Integer; x, y: TDateTime; begin E.Msg := TStringlist.Create; max := Length(Entries); for i:=0 to max-1 do for j:=0 to max-1 do begin DateSeparator := '.'; ShortDateFormat := 'dd.mm.yyyy'; LongTimeFormat := 'hh:nn:ss.zzz'; if Aufsteigend = True then begin x := StrToDateTime(Entries[i].DatumZeit); y := StrToDateTime(Entries[j].DatumZeit); end else begin x := StrToDateTime(Entries[j].DatumZeit); y := StrToDateTime(Entries[i].DatumZeit); end; if x > y then begin E := Entries[i]; Entries[i] := Entries[j]; Entries[j] := E; end; end; E.Msg.Clear; end; procedure InitFillEntries(Liste: TStringList); var i, zeilen, j: Integer; Inhalt: TStringlist; begin Inhalt := TStringlist.Create; if Length(Entries) > Liste.Count then begin for i := 0 to Length(Entries) - 1 do begin Entries[i].Msg.Clear; Entries[i].User := ''; Entries[i].DatumZeit := ''; end; end; SetLength(Entries, Liste.Count); for i := 0 to Length(Entries) - 1 do begin if FileExists(Liste[i]) then Inhalt.LoadFromFile(Liste[i]) else begin ShowMessage(Liste[i] + #13 + 'does not exist.'); Exit; end; Entries[i].User := Inhalt.Strings[0]; Entries[i].DatumZeit := Inhalt.Strings[1]; Entries[i].Msg := TSTringlist.Create; Entries[i].Msg.BeginUpdate; Entries[i].Msg.LoadFromFile(Liste[i]); Entries[i].Msg.Delete(0); Entries[i].Msg.Delete(0); Entries[i].Msg.EndUpdate; end; Sortieren(AufAb); Inhalt.Free; end; procedure PassEntries; var i, c, j: Integer; L, laden: TStringlist; Liste: TStringlist; s, dir: String; begin L := TStringlist.Create; Liste := TStringlist.Create; Laden := TStringlist.Create; dir := ExtractFilePath(ParamStr( 0 ))+'dbchat\'; GetFilesInDirectory(dir, '*.txt', Liste, False, True); L.BeginUpdate; InitFillEntries(Liste); //Array Füllen for i := 0 to Length(Entries) - 1 do begin L.BeginUpdate; L.Add(Entries[i].User); L.Add(Entries[i].DatumZeit); L.Add(''); L.Add(Trim(Entries[i].Msg.Text)); for c := 0 to 19 do s := s + Form1.EDiv.Text; L.Add(s); s := ''; end; L.EndUpdate; Form1.MOutput.Lines.Clear; Form1.MOutput.Lines.Assign(L); Liste.Free; laden.Free; L.Free; end; function RandomString(const len: Integer; const CharSet: string): string; [...] end; procedure TForm1.BSendClick(Sender: TObject); [...] end; procedure TForm1.BSortClick(Sender: TObject); begin [...] end; procedure TForm1.BRefreshClick(Sender: TObject); begin PassEntries; end; procedure TForm1.FormCreate(Sender: TObject); var dir : string; begin Randomize; // Get the current directory dir := GetCurrentDir; if DirectoryExists('dbchat') = True then begin AufAb := True; PassEntries; end else begin CreateDir('dbchat'); ShowMessage('Directory created:' + #13 + dir + 'dbchat'); end; MMessage.Lines.Clear; end; procedure TForm1.FormDestroy(Sender: TObject); var i: Integer; begin //Leeren for i := 0 to Length(Entries) - 1 do begin Entries[i].Msg.Clear; Entries[i].User := ''; Entries[i].DatumZeit := ''; end; SetLength(Entries, 0); end; end. |
AW: Memo lässt Zeilen verschwinden
Delphi-Quellcode:
Das ist ja der Teil um den es geht, und abgesen von s='' (das sollte vor for c:=0... stehen) sehe ich da nichts erwähnenswertes.
....
InitFillEntries(Liste); //Array Füllen for i := 0 to Length(Entries) - 1 do begin L.BeginUpdate; L.Add(Entries[i].User); L.Add(Entries[i].DatumZeit); L.Add(''); L.Add(Trim(Entries[i].Msg.Text)); for c := 0 to 19 do s := s + Form1.EDiv.Text; L.Add(s); s := ''; end; L.EndUpdate; Form1.MOutput.Lines.Clear; Form1.MOutput.Lines.Assign(L); .... Zitat:
Gruß K-H |
AW: Memo lässt Zeilen verschwinden
Wie kommen die Daten in die Dateien? Kann es sein, dass da noch irgendwelche Steuerzeichen von der Übertragung drin stehen?
|
AW: Memo lässt Zeilen verschwinden
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
@Luckie: Sorry, da war Zensursula etwas übereifrig. Beim Speichern kann eigentlich auch nix schief laufen, da die txt-Dateien alle vollständig sind. Hier die OnClick vom Senden-Button:
Delphi-Quellcode:
procedure TForm1.BSendClick(Sender: TObject);
var L: TStringList; s1, s2, p: String; begin if EUser.Text = '' then begin ShowMessage('Chatting without a name sucks.'); EUser.SetFocus; Exit; end; if MMessage.Lines.Count = 0 then begin ShowMessage('Chatting without writing something sucks.'); MMessage.SetFocus; Exit; end; L := TStringList.Create; L.BeginUpdate; L.Clear; L.Add(EUser.Text); L.Add(FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz', now)); L.AddStrings(MMessage.Lines); if DirectoryExists('dbchat') then begin s1 := RandomString; p := ExtractFilePath(ParamStr( 0 ))+'\dbchat\' + s1 + '.txt'; while FileExists(p) = True do begin ShowMessage('FileExists'); s1 := RandomString; p := ExtractFilePath(ParamStr( 0 ))+'\dbchat\' + s1 + '.txt'; end; L.SaveToFile(p); end; L.EndUpdate; L.Free; PassEntries; MMessage.Lines.Clear; MMessage.SetFocus; end; Die EXE habe ich beigelegt, bitte versucht mal 3 oder 4 Einträge anzulegen und danach die Sortierung nach Datum umzukehren; ihr werdet sehen, dass nur bei einem Eintrag was faul ist. DANKE! |
AW: Memo lässt Zeilen verschwinden
Eilmeldung: Ich habe gerade beschlossen keine einzelnen Dateien mehr zu erstellen, sondern pro user genau eine Datei anzulegen, dann stresst Dropbox nicht so oft rum. Verstehen würde ich das Problem von weiter oben trotzdem gern, also wenn jemand eine spontane Eingebung wär ich sehr dankbar =)
|
AW: Memo lässt Zeilen verschwinden
Liste der Anhänge anzeigen (Anzahl: 3)
Ok, wie es ausschaut, habe ich doch irgendeinen Denkfehler gemacht, denn auch in der neuen Version, bei der pro Chat-User immer nur eine txt angelegt wird, wird die Nachricht des vorletzten Eintrags ausgelassen.
Und weil das nicht schon nervig genug ist, wird auch nur die letzte Zeile einer Nachricht angezeigt. Bitte bitte helft mir, ich stehe so kurz vorm Ziel und Verzweifeln. Zur Veranschaulichung habe ich die Prozeduren zum Füllen des Arrays und Darstellung im Memo etwas kommentiert, hoffentlich hilft's.
Delphi-Quellcode:
EDIT:
//################################################### Deklaration
type TEntry = record User: String[25]; Msg: TStringList; DatumZeit: String; end; TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; BSend: TButton; MOutput: TMemo; MMessage: TMemo; EUser: TEdit; Label1: TLabel; EDiv: TEdit; Label2: TLabel; BSort: TButton; Icons: TImageList; BRefresh: TButton; procedure FormCreate(Sender: TObject); procedure BSendClick(Sender: TObject); procedure BSortClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BRefreshClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; Entry: TEntry; Entries: Array of TEntry; AufAb: Boolean; //################################################### Deklaration Ende {...verschiedene Funktionen...} //################################################### Sortieren procedure Sortieren(Aufsteigend: Boolean); var E: TEntry; i, j, max: Integer; x, y: TDateTime; begin E.Msg := TStringlist.Create; max := Length(Entries); for i:=0 to max-1 do for j:=0 to max-1 do begin DateSeparator := '.'; ShortDateFormat := 'dd.mm.yyyy'; LongTimeFormat := 'hh:nn:ss.zzz'; if Aufsteigend = True then begin x := StrToDateTime(Entries[i].DatumZeit); y := StrToDateTime(Entries[j].DatumZeit); end else begin x := StrToDateTime(Entries[j].DatumZeit); y := StrToDateTime(Entries[i].DatumZeit); end; if x > y then begin E := Entries[i]; Entries[i] := Entries[j]; Entries[j] := E; end; end; E.Msg.Clear; end; //################################################### Array füllen procedure InitFillEntries(Liste: TStringList); var i, eintrAuf, c: Integer; Inhalt, temp: TStringlist; PosisAuf, PosisZu: Array of Integer; f: String; begin Inhalt := TStringlist.Create; temp := TStringlist.Create; //Array leeren for i := 0 to Length(Entries) - 1 do begin Entries[i].Msg.Clear; Entries[i].User := ''; Entries[i].DatumZeit := ''; end; SetLength(Entries,0); //Array leeren Ende //Alle TXT-Dateien in "temp" reinladen | "Liste" enthält die Filenames for i := 0 to Liste.Count - 1 do begin f := Liste[i]; if FileExists(f) then Inhalt.LoadFromFile(f); temp.BeginUpdate; temp.AddStrings(Inhalt); temp.EndUpdate; end; //TXT-Dateien Ende eintrAuf := 0; //Nachrichtenzähler nullen SetLength(PosisAuf, 0); //Start-Merker nullen SetLength(PosisZu, 0); //Ende-Merker nullen //"temp" scannen for i := 0 to temp.Count - 1 do begin if temp.Strings[i] = '{{' then //Start eines Beitrags | Start-Merker begin Inc(eintrAuf); SetLength(PosisAuf, Length(PosisAuf)+1); PosisAuf[High(PosisAuf)] := i; end; if temp.Strings[i] = '}}' then //Ende eines Beitrags | Ende-Merker begin SetLength(PosisZu, Length(PosisZu)+1); PosisZu[High(PosisZu)] := i; end; end; SetLength(Entries, eintrAuf); //Array auf die Anzahl der Einträge setzen for i := 0 to eintrAuf-1 do //Array durchlaufen begin Entries[i].User := temp[PosisAuf[i]+1]; //Übergabe aus "temp" --> User-Name Entries[i].DatumZeit := temp[PosisAuf[i]+2]; //Übergabe aus "temp" --> Datum/Zeit for c := PosisAuf[i]+1 to PosisZu[i] - 1 do //Zeilenweise Übergabe aus "temp" --> Nachricht begin Entries[i].Msg := TStringList.Create; Entries[i].Msg.Add(temp.Strings[c]); end; end; //Leichen begraben SetLength(PosisAuf, 0); SetLength(PosisZu, 0); Inhalt.Clear; temp.Clear; end; //################################################### An Memo Übergeben procedure PassEntries; var i, c: Integer; L: TStringlist; Liste: TStringlist; s, dir: String; begin L := TStringlist.Create; //Zukünftiger Inhalt vom Memo Liste := TStringlist.Create; //Liste der TXT-Dateien dir := ExtractFilePath(ParamStr( 0 ))+'dbchat\'; GetFilesInDirectory(dir, '*.txt', Liste, False, True); //Alle TXT-Dateien in Verz. "dbchat" einlesen L.BeginUpdate; L.Clear; InitFillEntries(Liste); //Array Füllen Sortieren(AufAb); //Array nach Datum/Zeit sortieren for i := 0 to Length(Entries) - 1 do //"L" befüllen begin L.BeginUpdate; L.Add(Entries[i].User); L.Add(Entries[i].DatumZeit); L.Add(''); for c := 0 to Entries[i].Msg.Count - 1 do //Zeilen aus der Nachricht holen begin L.Add(Entries[i].Msg[c]); end; for c := 0 to 19 do s := s + Form1.EDiv.Text; //20 Zeichen als Trennlinie L.Add(s); s := ''; end; L.EndUpdate; Form1.MOutput.Lines.Clear; // "L" an Memo übergeben Form1.MOutput.Lines.Assign(L); Liste.Free; //Freigeben L.Free; //Scrollen if AufAb = True then Form1.MOutput.Perform(EM_LineScroll, 0 , Form1.MOutput.Lines.Count-1); end; Ich habe den Anhang um den Screenshot "debugger.png" erweitert. Dieser zeigt, was sich tatsächlich im Array verbirgt. Username ist ok, Datum/Zeit ist ok. Aber warum steht unter Msg (TStringlist) nicht der Text? Das macht mich echt mürbe -.- EDIT2:
Delphi-Quellcode:
Ich hatte die Stringlist an der falschen Stelle created. Nun funzen zumindest alle Einträge bis auf den vorletzten. Sry für den monolog, aber vllt. sieht es sich ja trotzdem noch einer an ;)
for i := 0 to eintrAuf-1 do //Array durchlaufen
begin Entries[i].User := temp[PosisAuf[i]+1]; //Übergabe aus "temp" --> User-Name Entries[i].DatumZeit := temp[PosisAuf[i]+2]; //Übergabe aus "temp" --> Datum/Zeit Entries[i].Msg := TStringList.Create; for c := PosisAuf[i]+3 to PosisZu[i] - 1 do //Zeilenweise Übergabe aus "temp" --> Nachricht begin Entries[i].Msg.Add(temp.Strings[c]); end; end; |
AW: Memo lässt Zeilen verschwinden
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ist der letzte Stand der EXE.
Würde mich freuen, wenn Ihr eine Idee bzgl. des Bugs habt. |
AW: Memo lässt Zeilen verschwinden
Was ist denn eigentlich jetzt der Stand der Dinge?
Versuch doch bitte noch einmal das Problem, genau zu beschreiben! Gruß K-H P.S. Ich schlage mich im allg. nicht darum, fremde Sourcen zu lesen, um mögliche Fehler zu finden. |
AW: Memo lässt Zeilen verschwinden
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Der Chat funktioniert mittlerweile fast einwandfrei. Das einzige Problem ist leider immer noch das vom Anfang, dass das Memo, welches den gesamten Chatlog anzeigt, bei der vorletzten Nachricht nur den User und das Datum mit Zeit anzeigt. Die Daten kommen aus einem Array of TEntry, welcher ein Record aus 2 Strings und einer Stringlist ist. Die Vermutung liegt nahe, dass die Übergabe ans Memo fehlerhaft ist (PassEntries). Diese Schlussfolgerung kommt daher, dass dieses Array vor der Darstellung analysiert und sortiert wird (also Datum/Zeit) und allein vom Datensatz her richtig befüllt ist. Das erkennt man daran, dass sowohl in der aufsteigenden als auch absteigenden Sortieung der vorletzte Message-Eintrag des Chat-Logs fehlt. Vielleicht ist es irgendein dubioser Zahlendreher, den ich einfach nicht sehe. Ich werde nochmal die aktuellste main.pas anhängen. Die Übergabe vom Array zum Memo passiert in "PassEntries". |
AW: Memo lässt Zeilen verschwinden
Viel wichtiger,
wie sieht der Eintrag für den Text in deinem array aus? "vorletzter" scheint mir sehr unwahrscheinlich, es sei denn Du fügst noch einen Standardsatz am Ende ein. Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:59 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 by Thomas Breitkreuz