please try this short easy code and look on the result.
About the code: At first it builds up a simple prae-text. And in a second
step it trys to modify this text a little bit with the 'SelStart',
'SelLength' and 'SelText'-technology.
After the prae-text is ready the end of line[3] is a '00:00:00'-expression.
Than the text-modifying tries to exchange its first '00' and replace it to a
'24'. And how you will see: This first '00' disapeares correctly BUT the
'24' comes up at a total other position (-> in line[8]; so expand your
RichEdit-control a little bit).
Code:
procedure TForm1.Button1Click(Sender: TObject);
var I, checkIt : integer;
AStr : String;
begin
RichEdit1.Perform(EM_SetLimitText,$7ffffffe,0);
checkIt := RichEdit1.Perform(EM_GetLimitText,0,0); // only to check it
once more
with RichEdit1 do begin
RichEdit1.Clear;
AStr := '---------------------';
RichEdit1.Lines.Add(AStr + '--------------');
for I := 1 to 2600 do RichEdit1.Lines.Add(AStr);
Lines.Insert(0,'on: ' + '00:00:00 ');
Lines.Insert(2,'on: ' + DateToStr(Now) + ' 00:00');
Lines.Insert(3,'on: ' + DateToStr(Now) + ' 24:00
00:00:00');
SelStart := Perform(EM_LINEINDEX,3,0) + 37; // = Pos of '00' in Line[3]
SelLength := 2;
SelText := '24'; // Excanging '00' with '24'
Label1.Caption := 'Chars = ' + IntToStr(Length(Lines.Text));
Label2.Caption := 'Lines = ' + IntToStr(Lines.Count);
// the next line without the comment-slashes triggers a Exception
// Lines.Add('triggers the Exception'); // <== brings a Exception
end;
end;
This code is really nothing special, everybody could have written it
somewhere in his programs. So everybody also could have such a bug in his
programs without knowing it! If you also run the last comment-line (at the
code-end) at least you will get an EOutOfResources-Exception and can react
on it. But also this Exception is not really convincing, the total-length of
the text is <64K. What you should write inside an error-message if this
happens?: "It's an error caused by Micro Soft..." ...or what else?
What someboddy should do, if such an error (with or without a following
exception) comes up?
Thx in advance
ARichEdit-victim?
This line is:
Lines.Insert(3,'on: ' + DateToStr(Now) + ' 24:00
00:00:00');
... and there must be 14 Blanks between the "24:00" and the "00:00:00":
Here the right code once more:
instead of this line:
Lines.Insert(3,'on: ' + DateToStr(Now) + ' 24:00
00:00:00');
take that:
FYI : When you change the subject of the thread, when it gets
archived, the thread is broken so no one (except those who
read this while the thread is still on the server) will ever
see your solution.
~ JD
Well, i can reproduce your problem on Win2K, using D2006. Unfortunately
TRichedit still uses version 1 of the richedit common control and you seem to
have run against a limitation of that control if you approach 64K characters
(the problem vanishes if you only add 2000 lines instead of the 2600, for
instance).
You may want to try one of the version 2/3 wrappers around (e.g. in the JEDI
VCL) to see if it has the same problem.
--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be
did you already report this bug in Quality Central?
Greetings
Markus
> did you already report this bug in Quality Central?
It's not a Delphi bug it's a RichEdit (=Microsoft) bug.
--
Pieter
And yet, perhaps Borland can work around it in their code.
--
Rudy.Velthuis {TeamB} http://velthuis.homepage.t-online.de/
"Give me a museum and I'll fill it."
-- Pablo Picasso (1881-1973)
> At 21:20:31, 11.12.2005, Pieter Zijlstra wrote:
>
> > Markus Humm wrote:
> >
> > > did you already report this bug in Quality Central?
> >
> > It's not a Delphi bug it's a RichEdit (=Microsoft) bug.
>
> And yet, perhaps Borland can work around it in their code.
I've tried to find a workaround, the best one I could find is not using
TRichEdit ;-) but one of the v2/3 wrappers instead. Maybe it's time
that Borland updates TRichEdit so that it uses RichEdit V3?
--
Pieter
Thx for your answer!
*downloadingAndInstallingTheJediComponents*, but now its not better: This
error is caused also by the TJvRichEdit-component ...with a small
line-difference only, but not more.
If i'm using the normal TRichEdit the first (loop-)line this error comes up
is (loop-index=) 2135. If i'm using a TJvRichEdit this error begins some
lines later. In this case i need 2232 loop-lines to produce this error too,
...and that's why these component is also not useable for me. It actually
seems, that this is really a bug of the richedit-control in generally and
not only one of the first version?
If i'm using a TMemo there is no error to see. But in my program its
important to have colored lines and sometimes an italic style.
Perhaps i should change this part of my program completely. Perhaps it would
be better to build up the whole text with a TStringList and after this is
done i transfer it into the TStrings of the RichEdit. Then i give all the
lines their colors and attributes followed by the output. Hope at least this
will work.
What else somebody can do here?
...no, but i never even know if there is a richedit-version later as this
mentioned v2/3.
Perhaps somebody should do that, who has more experiences in doing that (and
time)!
You are all have been instructed in doing this! :-)
Greetings
ARichEditVictim
> I've tried to find a workaround, the best one I could find is not using
> TRichEdit ;-) but one of the v2/3 wrappers instead. Maybe it's time
> that Borland updates TRichEdit so that it uses RichEdit V3?
That would be one workaround. <g>
--
Rudy.Velthuis {TeamB} http://velthuis.homepage.t-online.de/
"The instinct of nearly all societies is to lock up anybody who is truly
free. First, society begins by trying to beat you up. If this fails, they
try to poison you. If this fails too, the finish by loading honors on
your head."
- Jean Cocteau (1889-1963)
Looks like it.
> Perhaps i should change this part of my program completely. Perhaps it would
> be better to build up the whole text with a TStringList and after this is
> done i transfer it into the TStrings of the RichEdit. Then i give all the
> lines their colors and attributes followed by the output. Hope at least this
> will work.
If you try that do not use richedit.lines := theStringlist, that does a
line-by-line copy. Use richedit.text := thestringlist.text.
> *downloadingAndInstallingTheJediComponents*, but now its not better:
> This error is caused also by the TJvRichEdit-component ...with a small
> line-difference only, but not more.
I've tried it with a TRichEdit98, no problems here.
> Perhaps i should change this part of my program completely. Perhaps
> it would be better to build up the whole text with a TStringList and
> after this is done i transfer it into the TStrings of the RichEdit.
> Then i give all the lines their colors and attributes followed by the
> output. Hope at least this will work.
There are some issues when trying to "colorize" an existing RichEdit
document afterwards as well.
> What else somebody can do here?
With TRichEdit there are some lame workarounds, but it can blow later
when you code is not the same as it is now.
BTW "Lines.Insert(0," looks like to be the trigger of all the
misbehaviour in this case.
1a) Setting SelStart to 0 before adding the last line will stop the AV
(any other value will still generate the AV).
SelStart := 0;
Lines.Add('triggers the Exception'); // <== brings a Exception
1b) Don't use Lines.Add but set SelText instead. This will never
generate exceptions ;-)
2) Change the order of the insert commands to
Lines.Insert(1,'on: ' + DateToStr(Now) +
' 24:00 00:00:00');
Lines.Insert(1,'on: '+DateToStr(Now)+' 00:00');
Lines.Insert(0,'on: '+'00:00:00 ');
And if all off above does not work you can try...
3) Before replacing the text (or after the inserts) write and
reread to/from a stream
// ...
ms := TMemoryStream.Create;
try
Lines.SaveToStream(ms);
ms.Position := 0;
Lines.LoadFromStream(ms);
finally
ms.Free;
end;
SelStart := SendMessage(Handle, EM_LINEINDEX, 3, 0) + 37;
SelLength := 2;
SelText := '24'; // Exchanging '00' with '24'
// ...
4) Fiddling with other things like making your initial AStr five
dashes longer will also make the problem go away (for the moment).
PS using D7.1 on XP pro SP2.
--
Pieter
> If i'm using the normal TRichEdit the first (loop-)line this error comes up
> is (loop-index=) 2135. If i'm using a TJvRichEdit this error begins some
> lines later. In this case i need 2232 loop-lines to produce this error too,
> ...and that's why these component is also not useable for me. It actually
> seems, that this is really a bug of the richedit-control in generally and
> not only one of the first version?
Yes, I seem to remember someone reporting very odd results from
EM_LINEINDEX, which tended to indicate that there was a 16-bit counter
buried in it.
Easy answer though, don't use it!
If you want to know where each line begins, for example you could use
FindText to look for and count occurrences of #13. (that's likely to be a
bit slow though!).
> If i'm using a TMemo there is no error to see. But in my program its
> important to have colored lines and sometimes an italic style.
Then you _probably_ need richedit..
Though in Delphi 1, which did not have Richedit I managed to do coloured
lines with an Owner-Drawn StringGrid (one column, no fixed cells)!
> ...no, but i never even know if there is a richedit-version later as this
> mentioned v2/3.
>
> Perhaps somebody should do that, who has more experiences in doing that (and
> time)!
Derive a TRichedit Descendant component.
Add private integer flibhandle;
Override CreateParams to read
inherited;
flibhandle:=LoadLibrary('Riched20.DLL');
CreateSubclass(Params,'RichEdit20A');
(and free the library in OnDestroy)
When you instantiate one of these you will have a Class 3 richedit with a
quite different set of bugs to investigate.
:).
EM_LINEINDEX cannot be the responsible factor here. Because - how the first
'00' of the original '00:00:00'-expression always disappeares if
EM_LINEINDEX would give a wrong value? The cut-out-step (for the
string-replacing) is absolutly correct - only the insert-step isn't work!
Greetings
ARichEditVictim
> > SelStart := Perform(EM_LINEINDEX,3,0) + 37;
> > SelLength := 2;
> > SelText := '24'; // Excanging '00' with '24'
>
> Yes, I seem to remember someone reporting very odd results from
> EM_LINEINDEX, which tended to indicate that there was a 16-bit counter
> buried in it.
That's the "fun" in this case EM_LINEINDEX does return the correct
number. Even the SelText := '24' starts OK by removing the '00' from
the correct location of the original text but then RichEdit starts to
boggle and places the replacement string somewhere else.
--
Pieter
> That's the "fun" in this case EM_LINEINDEX does return the correct
> number. Even the SelText := '24' starts OK by removing the '00' from
> the correct location of the original text but then RichEdit starts to
> boggle and places the replacement string somewhere else.
Odd!
Even using Seltext exclusively?
(Your advice to avoid modifying text by lines.insert, or lines.anythingelse
is good).
Well then I think I'd try splitting it into 2 parts.
SelStart:=psn;
SelLength:=2;
SelText:='';
SelStart:=psn;
SelLength:=0;
SelText:='24';
I do know of one bug in richedit that I found a while back. Going by memory,
so I may not have the details right, but basically if you add text with an
embedded l/f to a richedit, it will replace the l/f with a crlf pair, but
will (apparently) only allocate space internally based on the original
string length. Add strings a few times, and the allocations/reallocations
eventually start producing bizarre results. I fixed the problem by ensuring
that I replaced all l/f's with lf+cr pairs before adding strings.
Greetings
Markus
> > That's the "fun" in this case EM_LINEINDEX does return the correct
> > number. Even the SelText := '24' starts OK by removing the '00' from
> > the correct location of the original text but then RichEdit starts
> > to boggle and places the replacement string somewhere else.
>
> Odd!
Yup ;-)
> Even using Seltext exclusively?
Yes
> (Your advice to avoid modifying text by lines.insert, or
> lines.anythingelse is good).
>
> Well then I think I'd try splitting it into 2 parts.
> SelStart:=psn;
> SelLength:=2;
> SelText:='';
> SelStart:=psn;
> SelLength:=0;
> SelText:='24';
Same result.
Just for the record, Windows ME, with a real RichEdit 1.0, has no
problems (*). It's just these pesky RichEdit 1.0 emulators (XP).
(*) Except for the "Insertion error" at the last Lines.Add() which
can be worked around by putting SelStart := GetTextLen; in front
of it.
BTW one serious difference between TRichEdit98 and TJvxRichEdit is that
TRichEdit98 is fully widestrings based...
--
Pieter
FWIW, this bug is NOT in RICHED20.DLL v4.0 and up.
--
Remko Bonte (Team JVCL) http://jvcl.sourceforge.net
>
> FWIW, this bug is NOT in RICHED20.DLL v4.0 and up.
hi,
as i read your post, i googled for a riched20.dll v4.0 and up. A dll version
5.30.23.12212 downloaded from http://www.dlldump.com/ (422KB) also brought
the error. After i read this and that i also searched on my own PC. Then in
a folder ...\Microsoft Shared\Office10 (though i have no Microsoft Office) i
found another one. It's length is 513KB. Version: No idea. But with this dll
the mistake disappeared. Now a question: Is it allowed to transfer this dll
together with my program, unpacking both into the folder where another user
want to put my program?
And: Are there any reasons, why someone shouldn't use this bigger/younger
riched20.dll (513KB) not in general on his whole system?
greetings
>> Odd!
> Yup ;-)
>> Even using Seltext exclusively?
> Yes
Oh, you've just reminded me of something - I did come across something
vaguely similar once.
I load a 4MB rtf file with about 5000 marked sections, then I delete all
those sections which are not in a list of about 300 I need to keep,
replacing deleted sections by '(deleted)'
A note in the code says
'{Windows gets confused when the offset of the text is over 143000}'
I remember, that the text was all screwed up at the end of the operation.
Anyway, the workaround I used was that I set a limit of 100000, and whenever
FindText returned > limit, I streamed the richedit out and back in again and
increased the limit. It seemed internal tables were getting scrambled and
reloading forced them to be regenerated.
(Also, I see I call Richedit1.Refresh after each deletion but I can't
remember if this is essential or even helps.)
This with a Class 3 homegrown component using riched20.dll version
5.30.23.1200
> Just for the record, Windows ME, with a real RichEdit 1.0, has no
> problems (*).
But you get new DLLs without knowing it just by installing an MS product. ;(
>It's just these pesky RichEdit 1.0 emulators (XP).
The XP(SP2) one seems to include nearly all the functionality you used to
need a Class 3 for. e.g. it responds to EM_SETZOOM.
> (*) Except for the "Insertion error" at the last Lines.Add() which
> can be worked around by putting SelStart := GetTextLen; in front
> of it.
Careful with that one. It needs fixing in Class 3s, needs a different
GTL_whatever constant, or it returns more than it should by counting
linefeeds as 2 chars where other parts (such as EM_FORMATRANGE) only count
1.
However a too-high value for selstart gets trimmed so I usually just use
SelStart:=$FFFFFF; to go to the end.
> BTW one serious difference between TRichEdit98 and TJvxRichEdit is that
> TRichEdit98 is fully widestrings based...
Is that supposed to be good or not?
The documents I process are only of interest to the British. There is no
need for me to be able to show them in Chinese. <g>
> Now a question: Is it allowed to transfer this dll
> together with my program, unpacking both into the folder where another user
> want to put my program?
I've heard (reputable andf knowledgeable) people answer both yes and no to
this, so I'm not sure.
> And: Are there any reasons, why someone shouldn't use this bigger/younger
> riched20.dll (513KB) not in general on his whole system?
Yes there is. It is slower.
So if you don't need the extra functionality, and speed is important to you,
you would be better off without it.
Also, as I indicated before, *all* the many richedit DLLs have (different)
bugs.. the trick is to look for workarounds that work with most of them.
-------
> Markus Humm wrote:
>> It's not a Delphi bug it's a RichEdit (=Microsoft) bug.
> Okay, has M$ something like QC somewhere?
LOL!
It would be busy!
> If not, how to get them to set smething like that up?
<I'm still laughing>
> > And: Are there any reasons, why someone shouldn't use this
bigger/younger
> > riched20.dll (513KB) not in general on his whole system?
>
> Yes there is. It is slower.
No, it isn't. You only have to take the code of my first post and now
additionally set a color or a style in each line you add into RichEdit.Lines
...then you will see: These office10-dll is faster. And: The higher the
line-numbers you add - the faster the execution of this office-dll (compared
with the normal dll in C:\WINNT\system32).
It seems this dll is an extra optimized and tuned dll to save and to oil
their own MS-office-applications ...so of course it also works faster with
bigger textes.
>> Yes there is. It is slower.
>
>
> No, it isn't.
I found that as soon as I installed younger newer DLLs, the time taken to do
a LoadFromFile of a big text increased by about 50%.
> It seems this dll is an extra optimized and tuned dll to save and to oil
> their own MS-office-applications
I don't think office even uses it.
e.g.
*delete* the riched?? dlls. (back them up first of course!)
Ask Word to save something as RTF.
It doesn't complain. It succeeds.
Conclusion , it is not using those DLLs.
Further proof, the RTF emitted from Word is nothing like that emitted by
TRichedit or even WordPad (which does use them pre WinXP).
NB on XP this test is difficult to do because the damn OS puts the DLLs back
when you delete them before you can make the test.
> [snipped]
> Anyway, the workaround I used was that I set a limit of 100000, and
> whenever FindText returned > limit, I streamed the richedit out and
> back in again and increased the limit. It seemed internal tables were
> getting scrambled and reloading forced them to be regenerated.
Yes, reloading seems to get the TRichEdit back on its feet again.
> > It's just these pesky RichEdit 1.0 emulators (XP).
> The XP(SP2) one seems to include nearly all the functionality you
> used to need a Class 3 for. e.g. it responds to EM_SETZOOM.
Once tried to use decimal tabs in V1 by using V2 paraformat. It did
work more or less but it had some side-effects (extra dots appearing in
the text).
> > BTW one serious difference between TRichEdit98 and TJvxRichEdit is
> > that TRichEdit98 is fully widestrings based...
> Is that supposed to be good or not?
Ah this note was based on a comment of the OP that the jvRichEdit (v3)
of JEDI had the same problem as the standard TRichEdit.
> The documents I process are only of interest to the British. There is
> no need for me to be able to show them in Chinese. <g>
You never know what the future brings... <g>
(it should be OK as long as they use Chinese windows versions)
--
Pieter
> NB on XP this test is difficult to do because the damn OS puts the
> DLLs back when you delete them before you can make the test.
I found that out too, it's almost like a virus ;-)
--
Pieter
> Then in a folder ...\Microsoft Shared\Office10 (though i
> have no Microsoft Office) i found another one. It's length is 513KB.
> Version: No idea.
Right click on the file select properties and check the version tab.
I think i have the same, mine is 5.40.11.2212 which is a v4.0 RichEdit.
--
Pieter
{\*\generator Riched20 5.40.11.2210;}
But your way returns more informations: version 4.0 too! *g*
Then finally i guess it's a absolut normal version of a Riched-dll and
everbody should have the permission to hand over it together with his
self-written program !?!
Greetings
Markus