AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Richedit schnell viele farbige Zeilen einfügen zu langsam
Thema durchsuchen
Ansicht
Themen-Optionen

Richedit schnell viele farbige Zeilen einfügen zu langsam

Ein Thema von NICK447 · begonnen am 14. Feb 2009 · letzter Beitrag vom 20. Feb 2009
Antwort Antwort
Seite 1 von 2  1 2      
NICK447

Registriert seit: 28. Jan 2008
7 Beiträge
 
Delphi 7 Professional
 
#1

Richedit schnell viele farbige Zeilen einfügen zu langsam

  Alt 14. Feb 2009, 20:09
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;
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 00:25
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;
  Mit Zitat antworten Zitat
NICK447

Registriert seit: 28. Jan 2008
7 Beiträge
 
Delphi 7 Professional
 
#3

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 08:34
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;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.153 Beiträge
 
Delphi 12 Athens
 
#4

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 10:07
Wenn du z.B. in einer StringList erstmal alles selber im RTF-Format erzeugst und das dann auf einmal an das Richedit übergibst?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
NICK447

Registriert seit: 28. Jan 2008
7 Beiträge
 
Delphi 7 Professional
 
#5

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 16:19
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
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.005 Beiträge
 
Delphi 2009 Professional
 
#6

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 16:47
Zitat von NICK447:
Das Richedit control erkennt die '\' und ersetzt durch doppelte
Quick & Dirty Lösung: die zusammengebauten Daten erst als Datei speichern und dann einlesen. Das wird wahrscheinlich schon ein vielfaches schneller sein.

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 ...
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.153 Beiträge
 
Delphi 12 Athens
 
#7

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 17:00
LoadFromStream sollte dann wohl besser sein.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
NICK447

Registriert seit: 28. Jan 2008
7 Beiträge
 
Delphi 7 Professional
 
#8

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 17:53
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;
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 15. Feb 2009, 18:16
Zitat von himitsu:
LoadFromStream sollte dann wohl besser sein.
Kann man, muss man aber gar nicht. Über eine Zuweisung an die Eigenschaft Text wird er RTF-Code auch angenommen.
  Mit Zitat antworten Zitat
Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#10

Re: Richedit schnell viele farbige Zeilen einfügen zu langsa

  Alt 17. Feb 2009, 13:06
Auf delphiforfun gibt es ein Beispiel für ein schnelles Highlighten von Wörtern.

Zitat:
Applying syntax formatting to a sizable Richedit file is quite slow. The technique used here is to intercept the WindowProc procedure used by TRichedit and let it paint the window which we then scan for words to by highlighted and rewrite them in the specified color.[...]
Thomas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:19 Uhr.
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