Solved

Delphi 7 :: TRichEdit Colored Lines :: Looses Format when Line Count too large

Posted on 2007-11-20
17
1,175 Views
Last Modified: 2013-11-23
Hi Experts,

1. Does the TRichEdit has any limit in Size / Line Count?

2. I have a procedure that colors a given line in a TRichEdit component. There is a little problem with the TRichEdit component, as soon as the line count is more than about 600-900 the RichEdit loads the saved information without any propery formatting and my colored lines are also gone. On application close I save TRichEdit.Lines.SaveToFile()  to file and when starting application I load again TRichEdit.Lines.LoadFromFile().
I think there is some kind of size limit because when line count is less 600 (est) it saves and loads and display contents correctly.

This is what the TRichEdit contents look like when it bombs out:

{\rtf1\ansi\deff0{\fonttbl{\f0\fnil MS Sans Serif;}}
{\colortbl ;\red0\green0\blue0;\red255\green0\blue0;}
\viewkind4\uc1\pard\cf1\lang1033\f0\fs16\{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033\{\\fonttbl\{\\f0\\fnil MS Sans Serif;\}\}
\par \{\\colortbl ;\\red0\\green0\\blue0;\\red128\\green0\\blue0;\\red0\\green128\\blue0;\\red255\\green0\\blue0;\}
\par \\viewkind4\\uc1\\pard\\cf1\\f0\\fs16 [2007/11/20 11:01:05 AM] New: D:\\\\B Destination\\\\44982.PREJIG
\par \\par [2007/11/20 11:01:05 AM] New: D:\\\\B Destination\\\\44987.PREJIG\\cf0
\par \\par \\cf1 [2007/11/20 11:01:05 AM] New: D:\\\\B Destination\\\\44980.PREJIG\\cf0
\par \\par \\cf2 [2007/11/20 11:01:09 AM] Production Order#: 7014564 has been replaced with latest.\\cf0
\par \\par \\cf1 [2007/11/20 11:01:09 AM] Production Order#: 7014564 Added.\\cf0
\par \\par \\cf2 [2007/11/20 11:01:09 AM] Production Order#: 7014565 has been replaced with latest.\\cf0
\par \\par \\cf1 [2007/11/20 11:01:09 AM] Production Order#: 7014565 Added.\\cf0
\par \\par \\cf2 [2007/11/20 11:01:09 AM] Production Order#: 7014566 has been replaced with latest.\\cf0
\par \\par \\cf1 [2007/11/20 11:01:09 AM] Production Order#: 7014566 Added.\\cf0


Thanks!
0
Comment
Question by:Marius0188
  • 7
  • 6
  • 4
17 Comments
 

Author Comment

by:Marius0188
ID: 20318666
When I set TRichEdit.PlainText := True
then it Loads properly but of course then my line coloring disappears.

Maybe this can help.... :)
0
 

Author Comment

by:Marius0188
ID: 20325875
Anyone that can help?
Or please if you know about a Free TRichEdit component that I can try out, let me know.

Thanks
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 20332987
depending on the os there is a memory-limit by default

not in mind correctly
- win9x -> 32kb
- winXP/NT/2000 -> 64kb

you can adjust this limit before loading editing with the API call

richedit1.perform(EM_EXLIMITTEXT,0,$0FFFFFFF);  //limit to 256MB

(you can play with the $0FFFFFFF paramater,
which is just the max amount of bytes a richedit can hold)

meikl ;-)
0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 13

Expert Comment

by:rfwoolf
ID: 20332989
If you're stuck, you should look up the W3Org standard for RTF files, i.e. learn how to code them. That way you can analyse the source code of an RTF file
I once learnt it about 3 years ago - and only superficially to complete the task I was doing. I've forgetten all about it now.
Anyway, on the other hand you might be correct - that there's a problem over a certain number of lines. To me the problem is either the source code of the RTF is invalid around those colour-less lines, or, it's a problem with the component/windows.

Good luck!
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 20332992
appendix,

for using above the richedit-unit must be added to the unit clause

meikl ;-)
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20332993
I posted my answer before seeing kretzschmar's. His answer sounds good. Give it a try.
0
 

Author Comment

by:Marius0188
ID: 20333045
HI Kretzschmar,

In regards to your post, #20332987
Do I need to only make a call to that method once for ex:
OnCreate of my main form

OR:

Should I make a call to that method BEFORE each time I add / edit a line to TRichEdit and also BEFORE loading and BEFORE saving to file?

Please advise.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 20333074
>Do I need to only make a call to that method once
yes, its only once needed
and (not sure, if it needed) before each load (.loadfromfile) (in case you load multiple files with the same instance)

meikl ;-)
0
 

Author Comment

by:Marius0188
ID: 20333156
I have implement that line of code but the problem still exists.
Any other suggestions?

Thanks for helping so far.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 20333233
bad, was my only idea about a limit

maybe you could show your code-sample?

meikl ;-)
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20333250
Try dumping the lines to an rtf file and opening it up in Word or Wordpad. See if it manages to colour the lines or not.
This will help in your diagnosis
0
 

Author Comment

by:Marius0188
ID: 20333426
Here is the procedure that writes the message to my log file and also to the TRichEdit
-------------------------------------------------------------------------------------------------------
procedure TfrmMain.WriteToLog(const ALogType :TLogType; AMessage: WideString);
var
  FTextFile :TextFile;
  TempMessage :String;
begin
  AssignFile(FTextFile, fServerLogFile);
  Try
    If FileExists(fServerLogFile) then Append(FTextFile)
    Else Rewrite(FTextFile);

    If not IsFilled(AMessage) then TempMessage := AMessage
    Else TempMessage := '[' + DateTimeToStr(Now) + '] ' + AMessage;


    Writeln(FTextFile, TempMessage);

    redtLogFile.Lines.Add(TempMessage);
    Case ALogType of
      logNormal: ColorRicheditLine(redtLogFile, redtLogFile.Lines.Count - 1, clBlack);
      logAttention: ColorRicheditLine(redtLogFile, redtLogFile.Lines.Count - 1, clGreen);
      logAlert: ColorRicheditLine(redtLogFile, redtLogFile.Lines.Count - 1, clMaroon);
      logError: ColorRicheditLine(redtLogFile, redtLogFile.Lines.Count - 1, clRed);
    end;
   
  Finally
    CloseFile(FTextFile);
    redtLogFile.Lines.SaveToFile(fServerLogFileRichEdit);
  end;
end;

-------------------------------------------------------------------------------------------------------



-------------------------------------------------------------------------------------------------------
Procedure ColorRicheditLine(const ARichEdit :TRichEdit; ARow :Integer; AColor :TColor);
begin
  With ARichEdit do
  begin
    SelStart := SendMessage(Handle, EM_LINEINDEX, ARow, 0);
    SelLength := Length(Lines[ARow]);
    SelAttributes.Color := AColor;
    SelLength := 0;
  end;
end;

-------------------------------------------------------------------------------------------------------
0
 

Author Comment

by:Marius0188
ID: 20348520
When opening the rtf file in wordpad is also have the wrong format.

Do you know about a free TRichEdit alternative component?
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20348893
Marius, surely if it displays wrong in Wordpad, then the sourcecode of the RTF is wrong?  Therefore a different richtext reader component is probably not the solution.
You need to perhaps study the RTF standards from W3O and study the RTF file, take out parts you don't need, scroll through until you find the problem. If you don't find the problem, at least you've eliminated some possibilities.
0
 

Author Comment

by:Marius0188
ID: 20350136
Mmmh, I hear what you say.
But why is it working fine up to a certain line count?
Anything less than 600-800 lines is displaying correctly.

Does that not rather shows it is something with the component because the code I use to highlight a line is consistent?
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 500 total points
ID: 20363868
Hi again,

i cant reproduce your problem (using TurboExplorer).
Have implemented an alternative Method, tests with a file with 5000 lines (206kb).
Also stoped the time:
Your Implementation: 170265 MilliSeconds
Alternative Implementation: 17203 MilliSeconds

My TestCase:


unit re_colorLines_u;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls;
 
type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit; //FileHolder
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    OpenDialog1: TOpenDialog;
    Button3: TButton;
    Splitter1: TSplitter;
    RichEdit2: TRichEdit;  //Target
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    fServerLogFile : string;
    fServerLogFileRichEdit : String;
    procedure WriteToLog(const ALogType :integer; AMessage: WideString);
    procedure WriteToLogNewVersion(const ALogType :Integer; AMessage: WideString);
  public
    { Public-Deklarationen }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
uses richedit;
 
 
//Load a file
procedure TForm1.Button1Click(Sender: TObject);
begin
  if opendialog1.Execute then
  begin
    //CleanUp
    richedit1.lines.Clear;
    richedit2.lines.Clear;
    //Init
    richedit1.perform(EM_EXLIMITTEXT,0,$0FFFFFFF);  //limit to 256MB
    richedit2.perform(EM_EXLIMITTEXT,0,$0FFFFFFF);  //limit to 256MB
    richedit1.Lines.LoadFromFile(opendialog1.FileName);
    fServerLogFile := opendialog1.FileName+'.fsl';
    fServerLogFileRichEdit  := opendialog1.FileName+'.fsl.rtf';
  end;
end;
 
//Caller ColorTheFileOriginalMethod
procedure TForm1.Button2Click(Sender: TObject);
var
  i : integer;
  start, ende : Longint;
begin
  start := getTickCount;
  for I := 0 to richedit1.lines.Count - 1 do
    WriteToLog(i mod 4, richedit1.lines[i]);
  ende := getTickCount;
  showmessage('TimeNeeded (MilliSeconds): '+IntTostr(ende-start));
end;
 
//Caller ColorTheFileNewMethod
procedure TForm1.Button3Click(Sender: TObject);
var
  i : integer;
  start, ende : Longint;
begin
  start := getTickCount;
  for I := 0 to richedit1.lines.Count - 1 do
    WriteToLogNewVersion(i mod 4, richedit1.lines[i]);
//save only once
  richedit1.Lines.SaveToFile(fServerLogFileRichEdit);
  ende := getTickCount;
  showmessage('TimeNeeded (MilliSeconds): '+IntTostr(ende-start));
end;
 
//Old Method
Procedure ColorRicheditLine(const ARichEdit :TRichEdit; ARow :Integer; AColor :TColor);
begin
  With ARichEdit do
  begin
    SelStart := SendMessage(Handle, EM_LINEINDEX, ARow, 0);
    SelLength := Length(Lines[ARow]);
    SelAttributes.Color := AColor;
    SelLength := 0;
  end;
end;
 
procedure TForm1.WriteToLog(const ALogType :Integer; AMessage: WideString);
var
  FTextFile :TextFile;
  TempMessage :String;
begin
  AssignFile(FTextFile, fServerLogFile);
  Try
    If FileExists(fServerLogFile) then Append(FTextFile)
    Else Rewrite(FTextFile);
 
    If not (AMessage = '') then TempMessage := AMessage
    Else TempMessage := '[' + DateTimeToStr(Now) + '] ' + AMessage;
 
 
    Writeln(FTextFile, TempMessage);
 
    richedit2.Lines.Add(TempMessage);
    Case ALogType of
      0: ColorRicheditLine(richedit2, richedit2.Lines.Count - 1, clBlack);
      1: ColorRicheditLine(richedit2, richedit2.Lines.Count - 1, clGreen);
      2: ColorRicheditLine(richedit2, richedit2.Lines.Count - 1, clMaroon);
      3: ColorRicheditLine(richedit2, richedit2.Lines.Count - 1, clRed);
    end;
 
  Finally
    CloseFile(FTextFile);
    richedit2.Lines.SaveToFile(fServerLogFileRichEdit);
  end;
end;
 
//New Method
procedure TForm1.WriteToLogNewVersion(const ALogType :Integer; AMessage: WideString);
var
  FTextFile :TextFile;
  TempMessage :String;
  Color : TColor;
begin
  AssignFile(FTextFile, fServerLogFile);
  Try
    If FileExists(fServerLogFile) then Append(FTextFile)
    Else Rewrite(FTextFile);
 
    If not (AMessage = '') then TempMessage := AMessage
    Else TempMessage := '[' + DateTimeToStr(Now) + '] ' + AMessage;
 
 
    Writeln(FTextFile, TempMessage);
 
    //richedit2.Lines.Add(TempMessage);
    Case ALogType of
      0: Color := clBlack;
      1: Color := clGreen;
      2: Color := clMaroon;
      3: Color := clRed;
    end;
 
    Richedit2.selstart := length(Richedit2.text);
    Richedit2.selAttributes.Color := Color;
    Richedit2.seltext := TempMessage+#10;
 
  Finally
    CloseFile(FTextFile);
    //guess must not done each line
    //richedit2.Lines.SaveToFile(fServerLogFileRichEdit);
  end;
end;
 
end.

Open in new window

0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 20363883
oops, of course line 80 must be richedit2 ;-)
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Path  to current project in Delphi. 2 79
delphi exception 7 64
Base1 Encode/Decode 3 77
Dynamically Created Query 3 55
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

786 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question