![]() |
Richedit schnell viele farbige Zeilen einfügen zu langsam
Hallo Forum ich verwende eine D7 eine Richedit Komponente und eine Listbox. Die Listbox hat ca 200.000 Zeilen die ich in einen Report in die Richedit komponente eintragen will. Die Listbox Daten sind eingefärbt um TX und RX Strings unterscheiden zu können. (Die Farbe wird in Listbox.Items.Objects gespeichert) Geht soweit alles wird aber ab 100.000 Zeilen sehr langsam. Ich glaube ich arbeite sehr umständlich um die Zeilen in die Richedit reinzubekommen. Hat jemand eine Idee wie man schnell viele VERSCHIEDEN gefärbte Textzeilen in eine Richedit Kompo. eintragen kann.
Danke fürs darüber schauen Nick
Delphi-Quellcode:
procedure TFmain.TntButton_generate_ReportClick(Sender: TObject); Var i,j,k,o : Integer; st1 : String; begin o := 0; k := 0; j := ListBox_HEX.Items.Count - 1; RichEdit1.Lines.BeginUpdate; for i:= 0 to j do Begin with RichEdit1 do Begin st1 := ListBox_HEX.Items[i]; SelStart := GetTextLen; SelAttributes.Color := TColor(ListBox_HEX.Items.Objects[i]); SelText := st1 + #13#10; end; end; RichEdit1.Lines.EndUpdate; end; |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Das Problem liegt wahrscheinlich an dem Aufruf von GetTextLen.
Diese Funktion zählt immer wieder von Vorne durch und braucht dadurch immer länger. Das führt dann zu einem quadratischen Anwachsen der benötigten Zeit.
Delphi-Quellcode:
procedure TFmain.TntButton_generate_ReportClick(Sender: TObject);
Var i : Integer; st1 : String; ins_pos : integer; list : TStrings; begin RichEdit1.Lines.BeginUpdate; // Zwischenvariable - spart Zeit und bringt Klarheit in den Code list := ListBox_HEX.Items; ins_pos := RichEdit1.GetTextLen; // am Anfang einmal die Einfügeposition ermitteln for i:= 0 to list.Count - 1 do Begin with RichEdit1 do Begin st1 := list.Items[i]; SelStart := ins_pos; SelAttributes.Color := TColor(list.Objects[i]); SelText := st1 + #13#10; { Einfügeposition weiterzählen. Hier bin ich mir nicht sicher, ob man den Zeilenumbruch als 2 Zeichen zählen muss oder nicht. Bitte selbst herausfinden. } Inc(ins_pos, Length(st1) + 2); end; end; RichEdit1.Lines.EndUpdate; end; |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
moin moin SX2008,
ich habe heute morgen mal Tests mit jeweils 50.000 Zeilen gemacht. Routine 1: 256 344 ticks ==> erst mal Strings reinkopieren dann Zeilen färben Routine 2: 33.797 ticks ==> Rückwärts zählen letzte Zeile zuerst einfügen die EinfügePos bleibt immer auf 0 Routine 3: 56.078 ticks ==> Dein Vorschlag ohne lokale Tstrings tja alles zu langsam z.B. Das erzeugen der Stringlist mit 50.0000 dauert nur ca. 2-3 sec. Im Moment ist das noch keine Lösung Grüsse Nick
Delphi-Quellcode:
procedure TFmain.TntButton_generate_ReportClick(Sender: TObject);
Var i,j,k,o : Integer; st1 : String; tick1,tick2 : Dword; begin tick1 := GetTickCount; j := ListBox_HEX.Items.Count - 1; RichEdit1.Lines.BeginUpdate; RichEdit1.Lines := ListBox_HEX.Items; for i:= 0 to j do Begin with RichEdit1 do Begin SelStart := SendMessage(Handle, EM_LINEINDEX, i, 0); SelLength := Length(Lines[i]); SelAttributes.Color := TColor(ListBox_HEX.Items.Objects[i]); end; end; RichEdit1.Lines.EndUpdate; tick2 := GetTickCount; tick2 := tick2 - tick1; Fmain.Memo_Status.Lines.Add('Tick : ' + inttostr(Tick2)); end; // Routine 2 procedure TFmain.TntButton_generate_ReportClick(Sender: TObject); Var i,j,k,o : Integer; st1 : String; tick1,tick2 : Dword; begin tick1 := GetTickCount; j := ListBox_HEX.Items.Count - 1; RichEdit1.Lines.BeginUpdate; for i:= j downto 0 do Begin with RichEdit1 do Begin st1 := ListBox_HEX.Items[i]; SelStart := 0; SelAttributes.Color := TColor(ListBox_HEX.Items.Objects[i]); SelText := st1 + #13#10; end; end; RichEdit1.Lines.EndUpdate; tick2 := GetTickCount; tick2 := tick2 - tick1; Fmain.Memo_Status.Lines.Add('Tick : ' + inttostr(Tick2)); end; // Routine 3 procedure TFmain.TntButton_generate_ReportClick(Sender: TObject); Var i,j,k,o,ins_Pos : Integer; st1 : String; tick1,tick2 : Dword; begin tick1 := GetTickCount; j := ListBox_HEX.Items.Count - 1; RichEdit1.Lines.BeginUpdate; for i:= 0 to j do Begin with RichEdit1 do Begin st1 := ListBox_HEX.Items[i]; SelStart := ins_Pos; SelAttributes.Color := TColor(ListBox_HEX.Items.Objects[i]); SelText := st1 + #13#10; inc(ins_Pos,length(st1) + 2); end; end; RichEdit1.Lines.EndUpdate; tick2 := GetTickCount; tick2 := tick2 - tick1; Fmain.Memo_Status.Lines.Add('Tick : ' + inttostr(Tick2)); end; |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Wenn du z.B. in einer StringList erstmal alles selber im RTF-Format erzeugst und das dann auf einmal an das Richedit übergibst?
|
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
ja darüber habe ich auch schon nachgedacht !! Das gespeicherte RTF in einen standard Editor geladen man sieht schön die "Tags" für Farbe.
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl {\f0\fnil\fcharset0 Courier New;}} {\colortbl ;\red255\green0\blue0;\red0\green0\blue255;} \viewkind4\uc1\pard\b\f0\fs16 Report \par \cf1 00166: 12 02 31 0a 00 00 00 00 \par \cf2 00176: f1 03 71 0a 01 00 00 00 \par \cf1 00189: 12 03 22 25 06 00 00 00 \par \cf2 00196: f1 05 62 25 06 00 fe 00 usw. usw. Die \cf1 \cf2 sind die Farben denke ich. Habe ich dann einfach voran gestellt und die Stringliste zeilenwesie kopiert. st1 := '\par \cf2 ' + st1 + #$0d + #$0a; aber das Resultat ist ... na ja ... beeindruckend. \\par \\cf1 00155: 12 02 31 0a 00 00 00 00 \\par \\cf2 00161: f1 03 71 0a 01 00 00 00 \\par \\cf1 00174: 12 03 22 25 06 00 00 00 Das Richedit control erkennt die '\' und ersetzt durch doppelte .. richtig schlau.. ne ich weis da im Moment nicht weiter .... Grüsse Nick |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Zitat:
Es gibt aber sicher noch eine Möglichkeit, den String im Speicher zusammenzubauen und dann dem RichEdit zuzuweisen (als StringStream oder MemoryStream), denn auslesen geht ja auch ... |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
LoadFromStream sollte dann wohl besser sein.
|
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
ja hört sich gut an Stream basteln rein mit den Daten und wieder raus in die Richedit...
und schon probiert ... Zeilen zusammensetzten mit Formatierung versehen in einen TStringStream schreiben. Wenn fertig komplett vom Stream in RichEdit laden. Ich mache da irgendetwas falsch die Formatierung wird so nicht genommen es werden wieder die '\ durch doppelt '\\ ersetzt. (Der Code ist nur mal quick & dirty zusammengenagelt) das Ergebniss ist alles in schwarz und meine \par \cf1 wieder mit doppelten '\\' und damit keine Formatierung im RTF da fehlt mir das Wissen wie das in den RTF gespeichert wird und wie die Komponente arbeitet. Danke für Eure Ideen. Gruss Nick
Delphi-Quellcode:
procedure TFmain.TntButton_generate_ReportClick(Sender: TObject);
Var i,j : Integer; st1,st2 : String; StrS : TStringStream; col : Tcolor; begin StrS := TStringStream.Create(''); j := ListBox_HEX.Items.Count - 1; // st1 := '{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;'; // StrS.WriteString(st1); // st1 := '{\colortbl ;\red255\green0\blue0;\red0\green0\blue255;'; // StrS.WriteString(st1); st1 := '\viewkind4\uc1\pard\b\f0\fs16 Report'; StrS.WriteString(st1); try for i:= 0 to j do Begin st1 := ListBox_HEX.Items[i]; col := TColor(ListBox_HEX.Items.Objects[i]); case col of clRED : st2 := '\par \cf1 '; clBLUE : st2 := '\par \cf2 '; end; StrS.WriteString(st2); StrS.WriteString(st1); end; StrS.Position := 0; RichEdit1.Lines.LoadFromStream(StrS); finally StrS.Free; end; end; |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Zitat:
|
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Auf
![]() Zitat:
|
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
So wird zumindest ein brauchbarer RTF-Code erzeugt:
Delphi-Quellcode:
procedure TFmain.TntButton_generate_ReportClick(Sender: TObject);
var i, j: Integer; st1, st2: String; StrS: TStringStream; col: TColor; begin StrS := TStringStream.Create(''); j := ListBox_HEX.Items.Count - 1; st1 := '{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Courier New;}}'; StrS.WriteString(st1); st1 := '{\colortbl ;\red255\green0\blue0;\red0\green0\blue255;}'; StrS.WriteString(st1); try for i:= 0 to j do begin st1 := ListBox_HEX.Items[i]; col := TColor(ListBox_HEX.Items.Objects[i]); case col of clRED : st2 := '\cf1 '; clBLUE : st2 := '\cf2 '; else st2 := '\cf0 '; end; StrS.WriteString(st2 + st1 + '\par'); end; st1 := '}'; StrS.WriteString(st1); StrS.Position := 0; RichEdit1.Lines.LoadFromStream(StrS); finally StrS.Free; end; end; |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
heute leider keine Zeit zum testen .. Werde Dir morgen berichten wie schnell das für 50.000 Zeilen geht danke für den Tipp mit dem brauchbaren RTF code..
Nick |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Hallo ich mal wieder... Blup das funktioniert so !! .. also 50.000 Lines mit "Blup's" Methode macht 23 sekunden meine bisher schnellste Methode (von hinten nach vorne und Einfügepos. auf 0 lassen) waren 33 sekunden. Ich habe noch ein Progress Bar rein gesetzt damit niemand denkt das Programm ist abgestürtzt ... Begeistert mich nicht aber ist so.. Ich habe teilweise 200.000 Zeilen in den Reports Gruss Nick
|
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Hallo
Da stellt sich die Frage nach dem Sinn einer Ausgabe von 200.000 Zeilen. |
Re: Richedit schnell viele farbige Zeilen einfügen zu langsa
Hi Toms... der Sinn .. gesamte Kommunikation eines Gerätes mit dem PC wird aufgezeichnet .. als rtf Report kann es gespeichert werden .. Die Farben machen Sinn damit man schnell sehen kann wer hat gesendet und was wurde empfangen. Das rtf Format ist durchsuchbar und kann auf jedem PC mit verschiedenen Programmen angezeigt werden ( Im schlechten Fall mit Wordpad) Ich weis das man kaum 200.000 Zeilen lesen wird aber manchmal will man bestimmte Stellen suchen und untersuchen.
Nick |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:46 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