Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can someone try and reproduce a D6/D7 bug with Delphi 2005?

1 view
Skip to first unread message

Gottfried Helms

unread,
Feb 1, 2005, 1:17:11 PM2/1/05
to
The bug occured in D6 & D7 running on Win98Se, but not on Win2K.
it would be interesting, whether this still exists in D2005
(and on which platform), and - hopefully - a competent one could
find the reason for it.

If you have an application which employs

- a tRichedit
- a tActionMainMenubar (doesn't need menuitems)

then the trichedit does not add lines correctly.
If you try to add stuff of about 64 KB, then eOutofResources-
messages will occur.

You can reproduce this behaviour if you have

- one button to create the tActionMainMenubar dynamically
- one button to destroy it dynamically

- one button to push lines into the richedit.
(I tried it with a block of 200 lines with 98 char,
pushing it 8 times to the richedit with one click)

If the ActionMainmenubar is present, you get the error-msg,
if it is not present, you don't, and every thing behaves nicely.

ActionMainMenubar1:=tactionmainmenubar.create(self);
ActionMainMenubar1.parent:=self;
for i:=1 to 8 do
Richedit1.lines.add(My20KBStrings);
// The error occurs

ActionMainmenubar1.destroy;
for i:=1 to 8 do
Richedit1.lines.add(My20KBStrings);
// No error

I could locate the error down to the Application.Menu-Wndproc;
both components add hooks to the event-loop.

If only the menuhook of tAMMB is disabled while pushing
data into the richedit, then everything is fine, that means
if I surround the pushing by an unhook/rehook-procedure

ActionMainMenubar1:=tactionmainmenubar.create(self);
ActionMainMenubar1.parent:=self;

ammb_unhook;
for i:=1 to 8 do
Richedit1.lines.add(My20KBStrings);
// No error
ammb_rehook;

the menubar and the richedit can coexist peacefully.

If you have written an application, which contains this two
components, you should check, whether it needs an appropriate fix.

This does not concern TactionManager, TActionToolbar and TMainmenu.
Some richedit-fixes are not safe, for instance I tried spoonworx-
richedit, which has the same faulty behaviour; the JvRichedit
is fine (but it is not fully compatible with tRichedit and you
may have things to adapt)

I put a message with more information at borlands-qualitycenter;
there is also a Test_ammb.exe (with source) attached for downloading.
(See Report 10668, comments,attachment,workaround)

I would like to know, whether this problem persists under D2005,
and for my own learning I would like to find out the reason
in the tRichedit-functionality. Some expert in that area around?

Regards -

Gottfried Helms

Bruce Roberts

unread,
Feb 1, 2005, 3:38:07 PM2/1/05
to

"Gottfried Helms" <he...@uni-kassel.de> wrote in message
news:ctoh4f$ps9$01$1...@news.t-online.com...

> The bug occured in D6 & D7 running on Win98Se, but not on Win2K.
> it would be interesting, whether this still exists in D2005
> (and on which platform), and - hopefully - a competent one could
> find the reason for it.

> then the trichedit does not add lines correctly.


> If you try to add stuff of about 64 KB, then eOutofResources-
> messages will occur.

Do you really think this is a bug? I don't. As soon as I see 64 KB and a
difference between Win98 & 2K I immediately think that the message is
probably correct. The o/s is running out of resources. Win98 is quite
limited in some areas. Beyond that, does the rich edit have its max length
set appropriately?


Gottfried Helms

unread,
Feb 1, 2005, 5:11:05 PM2/1/05
to
Am 01.02.05 21:38 schrieb Bruce Roberts:

>
>
> Do you really think this is a bug? I don't. As soon as I see 64 KB and a
> difference between Win98 & 2K I immediately think that the message is
> probably correct. The o/s is running out of resources. Win98 is quite
> limited in some areas. Beyond that, does the rich edit have its max length
> set appropriately?
>
>
Hi Bruce-

well I think it is a bug, since such an interaction between two
menu-involving components surely should be outlined, if it were
a feature ...;-)
But anyway, things are correctly set and richedit is capable
of all things as it should be in a complete normal manner, as long as
the tAMMB-menu-hook is not present.

It is an especially nasty bug, since it occurs only under certain
circumstances, and nearly certainly only at the runtime at your
customer: I had the program running long time perfectly without
problems; then one day I upgraded all my menus etc via Actionmanager
and Actionmainmenubars. No problems when I tested the polished new
application.
But recently I produced a longer session-protocol (in one of the
richedits) and encountered unpredictable eOutofResources-exceptions.
(Lucky me - it is not yet a commercial application...;-) )

Delphi2005 is new and the current state-of-the-art-Delphi; so I
would like to know, whether they have prevented this behaviour
or it is still to be expected in Richedit/Actionmainmenubar-
employing applications - I think, there are some of such around.

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

Why I'm interested in an understanding of things beyond merely
getting workarounds is, that I possibly could learn some more
abut windows-hooks and the event-message-system.

Another observation:
The outofresources-msg is also not consistent; I mean the accepting
of lines by the richedit is not exactly predictable in terms of
linenumbers or kilobytes: sometimes it accepts more, sometimes less.
Completely messy is the behaviour, if you have filled the richedit
up to 32764-lines: no more outorresources msg's then - but the
adding is still "slightly corrupt": istead of consequently adding
1608 lines (in my example), its linecount.property documents sometimes
1609, sometimes 1607 additional lines...
The lines.add() procedure apparently triggers a lot of windows-
events which I could track by inserting a protocol into the
menuhook-procedure of the tAMMB-component (I've the source code
with Delphi). Maybe it is just an event-overflow - which could
be the reason, that a Win2K-Installation performs better. I'm
focusing on that idea, currently. But then I think, a Win2K-
installation should be tested with just a higher amount of
data pushed into the richedit.

Regards -

Gottfried


Gottfried Helms

unread,
Feb 1, 2005, 5:19:04 PM2/1/05
to
Well I'm just adding a most simple source-code for testing
that bug (D6-code).
May be, you just can copy&paste it in a new D2005-application;
I've provided the sourcecode, the unit and the form in text-format)
below.

Gottfried Helms

====================================================================
// The "Programm"

program Test;

uses
Forms,
Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm2, Form2);
form2.Show;
Application.Run;
end.

====================================================================
// the forms-Unit

unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ActnCtrls, ToolWin, ActnMan,
ActnMenus, ActnList, Menus, ExtCtrls;

type
TForm2 = class(TForm)
RichEdit1: TRichEdit;
Panel1: TPanel;
kn_AMMB_erz: TButton;
KN_RE_Stopf: TButton;
kn_AMMB_del: TButton;
procedure kn_AMMB_erzClick(Sender: TObject);
procedure kn_AMMB_delClick(Sender: TObject);
procedure KN_RE_StopfClick(Sender: TObject);

private
{ Private-Deklarationen }

public
{ Public-Deklarationen }
ActionMainMenuBarX: TActionMainMenuBar;
function RE_Stopfen(re:trichedit;const anz:integer):integer;

end;

var
Form2: TForm2;

implementation
{$R *.dfm}


// Eine ActionMainmenubar zur Laufeit erzeugen
procedure TForm2.kn_AMMB_erzClick(Sender: TObject);
begin
if assigned(ActionMainMenuBarX) then exit;

ActionMainMenuBarX:= TActionMainMenuBar.create(self);
with ActionMainMenuBarX do
begin
parent:=self;
Color :=clWhite;
borderwidth:=4;
end;

end;


// die ActionMainmenubar zur Laufeit löschen
procedure TForm2.kn_AMMB_delClick(Sender: TObject);
begin
if not assigned(ActionMainMenuBarX) then exit;

ActionMainMenuBarX.Free;
ActionMainMenuBarX:= nil;
end;

// 160 KB String in Richedit zu schreiben versuchen
procedure TForm2.KN_RE_StopfClick(Sender: TObject);
begin
case RE_Stopfen(richedit1,8) of
0: application.MessageBox('Ok, jetzt hats geklappt','OK');
1: application.MessageBox('Richedit Kapazität limitiert','Fehler');
2: application.MessageBox('Richedit sonstiger Fehler','Fehler');
end;
end;

// 160 KB String in Richedit schreiben
// you may increase the amount of lines-to-write to stress the event-msg-loop more
// in case you test it on a Win2K-platform
function TForm2.RE_Stopfen(re:trichedit;const anz:integer):integer;
const
zeiLae=98;
Zeilen=200;
var
zeile,block:ansistring;
i:integer;
begin

setlength(zeile,zeiLae);
for i:=1 to ZeiLae do
if i mod 10=0
then Zeile[i]:=' '
else Zeile[i]:=chr(random(36)+48);


Block:='';
for i:=1 to Zeilen do
Block:=Block+Zeile+#13#10;

result:=0; // das signalisiert OK
try
for i:=1 to anz do
re.Lines.add(Block);

except
on eoutofresources do result:=1;
else result:=2;
end;
end;

end. // unit


====================================================================================
//The Formular-Design

object Form2: TForm2
Left = 684
Top = 334
Width = 458
Height = 481
Caption = 'Form2'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object RichEdit1: TRichEdit
Left = 0
Top = 65
Width = 450
Height = 389
Align = alClient
Lines.Strings = (
'RichEdit1')
ScrollBars = ssBoth
TabOrder = 0
WantTabs = True
WordWrap = False
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 450
Height = 65
Align = alTop
TabOrder = 1
object kn_AMMB_erz: TButton
Left = 40
Top = 8
Width = 75
Height = 25
Caption = 'Erzeugen'
TabOrder = 0
OnClick = kn_AMMB_erzClick
end
object KN_RE_Stopf: TButton
Left = 144
Top = 16
Width = 75
Height = 25
Caption = 'Test Richedit'
TabOrder = 1
OnClick = KN_RE_StopfClick
end
object kn_AMMB_del: TButton
Left = 40
Top = 32
Width = 75
Height = 25
Caption = 'Löschen'
TabOrder = 2
OnClick = kn_AMMB_delClick
end
end
end
==========================

Terry Russell

unread,
Feb 1, 2005, 9:12:06 PM2/1/05
to

"Gottfried Helms" <he...@uni-kassel.de> wrote in message
news:ctoh4f$ps9$01$1...@news.t-online.com...
> The bug occured in D6 & D7 running on Win98Se, but not on Win2K.
> it would be interesting, whether this still exists in D2005
> (and on which platform), and - hopefully - a competent one could
> find the reason for it.
>
> If you have an application which employs
>
> - a tRichedit
> - a tActionMainMenubar (doesn't need menuitems)
>
> then the trichedit does not add lines correctly.
> If you try to add stuff of about 64 KB, then eOutofResources-
> messages will occur.

google richedit|trichedit line insertion
is it that?

many things seem to trigger it
e.g. some dialog box accelerator apps

use selstart method

....search cut paste...
CPU tracing shows richstrings fails when it gets -1 for EM_LINEINDEX
near 32k or 64k , also sometimes invalid window handle..

Workaround, a bit of flicker, a bit of delay

add as file , stream or .text

or
richedit1.selstart:=-1;
richedit1.sellength:=0;
richedit1.seltext:=s+#10;
// this is basically what append does anyway.

or
sl:tstringlist;
..
sl.add(...);
..
richedit1.selstart:=-1;
richedit1.sellength:=0;
richedit1.selText:=sl.text;

or
V2 Richedit works, Rxrichedit etc , at least for now.
..200502..I recall rx also had the problem???


detect and divert..
or override richedit line insert
never give it a chance to happen


var waskallywabbit:boolean=false;
try
if waskallywabbit then
begin
richedit1.selstart:=-1;
richedit1.sellength:=0;
richedit1.seltext:=s+#10;
else
richedit.lines.add(s);
except
on e:exception do
begin
waskallywabbit:=true;
richedit1.selstart:=-1;
richedit1.sellength:=0;
richedit1.seltext:=s+#10;
end;
end;//try


Jamie

unread,
Feb 2, 2005, 4:55:24 PM2/2/05
to
your problem is OS not compiler.
WIn98 is use larger memos, you need to use the
WM_SETLIMITTEXT message on to increase the size of the
memo.
for the rest of your problems? i don't know!

VBDis

unread,
Feb 3, 2005, 4:26:46 AM2/3/05
to
Im Artikel <ctour1$qn2$04$1...@news.t-online.com>, Gottfried Helms
<he...@uni-kassel.de> schreibt:

> But recently I produced a longer session-protocol (in one of the
> richedits) and encountered unpredictable eOutofResources-exceptions.

As already stated, OutOfResources is an OS topic. You only can try to reduce
the required resources in your program, at least when running on Win9x.

DoDi

Gottfried Helms

unread,
Feb 3, 2005, 10:52:42 AM2/3/05
to
Am 02.02.05 22:55 schrieb Jamie:

>
> your problem is OS not compiler.
> WIn98 is use larger memos, you need to use the
> WM_SETLIMITTEXT message on to increase the size of the
> memo.
> for the rest of your problems? i don't know!
>
Well, it's not a matter of wm_setlimittext. The richedit
is well working without the menu-interference of tAction-
Mainmenubar. The wm_exLimittext does not change anything.
Even the richedit works fine without this message, at least
in D6.

Regards-
Gottfried Helms

Gottfried Helms

unread,
Feb 3, 2005, 10:59:57 AM2/3/05
to
Am 02.02.05 03:12 schrieb Terry Russell:

>
> google richedit|trichedit line insertion
> is it that?

Well I'll see, perhaps the problem was mentioned elsewhere
already; the phrase "line insertion" didn't come into my
mind. Thanks!

>
> many things seem to trigger it
> e.g. some dialog box accelerator apps
>
> use selstart method

Hmm, may be, that's a workaround. I'm just somehow
used to the lines.add-method.
Cut&Paste is only fine in the GUI/User-interaction.
The position, where I encountered the problem was
in a session-protocol-window: no user interaction assumed.

>
> or
> sl:tstringlist;
> ..
> sl.add(...);
> ..
> richedit1.selstart:=-1;
> richedit1.sellength:=0;
> richedit1.selText:=sl.text;
>
> or
> V2 Richedit works, Rxrichedit etc , at least for now.
> ..200502..I recall rx also had the problem???

Did it? With the implementation as JvRichedit the
thing is working fine. (Latest version of Jedi-Tools)

>
> var waskallywabbit:boolean=false;
;-))) Hope the compiler does not break...

> try
> if waskallywabbit then
> begin
> richedit1.selstart:=-1;
> richedit1.sellength:=0;
> richedit1.seltext:=s+#10;
> else
> richedit.lines.add(s);
> except
> on e:exception do
> begin
> waskallywabbit:=true;
> richedit1.selstart:=-1;
> richedit1.sellength:=0;
> richedit1.seltext:=s+#10;
> end;
> end;//try
>

I'll see. The seltext-property may be a solution.
On the other hand: I'd much more like a consistent
component, whose functionality is not dependent on
another standard-component as the ActionMenubar...

Thanks for your input.
But still I'd like to know, whether things happen
in D2005 as well. Do you have D2005?

Regards-

Gottfried Helms

Gottfried Helms

unread,
Feb 3, 2005, 11:08:05 AM2/3/05
to
Am 03.02.05 10:26 schrieb VBDis:

No, the outofresources-message is triggered by the
*richedit-control*; in the Insert-method as a last
action the method checks, whether the actual size of
text in the richedit equals the size, which is computed
from the old length and the length, which should be added.
There occurs a mismatch, and then the *insertion*-method
triggers the eOutofresources-event.

If the richedit-control encounters a difference (running in
that internal insertion-procedure), then *it* raises an
"EoutOfResources"-Exception. Nothing with OS...

Only the *reason* why some lines could not be added could
be caused by some OS-shortages, since each line-adding seems
to create a windows-message; and the implemention of the
richedit may install some type of recursion - don't know.

Also it may be of interest, that all these messages *only*
occur if the line-number is <32767 (maxint of 16-bit-integer).
Once the line number is greater, no msg occurs (though the
line insertion is still not correct)

Regards-

Gottfried Helms


VBDis

unread,
Feb 4, 2005, 10:59:24 PM2/4/05
to
Im Artikel <cttiad$jnm$04$1...@news.t-online.com>, Gottfried Helms
<he...@uni-kassel.de> schreibt:

>Only the *reason* why some lines could not be added could


>be caused by some OS-shortages, since each line-adding seems
>to create a windows-message; and the implemention of the
>richedit may install some type of recursion - don't know.

Most probably the reason is a lack of memory, what may be cured by assigning
more memory to the richedit control, as already posted. The control also may
catch an according OS exception somewhere else, and throw an equivalent
exception when the catch is detected later. A TRichEdit only is a wrapper
around a Windows rich text edit control, and the implementation of that control
can vary on every Windows installation. Can you ask your customer for the exact
version of the installed rich text control?

>Also it may be of interest, that all these messages *only*
>occur if the line-number is <32767 (maxint of 16-bit-integer).
>Once the line number is greater, no msg occurs (though the
>line insertion is still not correct)

You should not assume that the richedit is organized in lines, internally. It's
more probable that it uses an single big buffer for the contents, which then is
mapped into a number of lines, depending on the current width of the control.
Consequently the use of SelStart and SelLength would be more efficient than
addressing specific lines.

The correspondence to line numbers <32767 indicates an bug to me, where higher
line numbers may be treated erroneously as negative numbers, which are handled
differently, most probably are not handled at all. The error may also occur for
line numbers >64K, where the sign bit of a word will be zero again. Buggy code
tends to produce weird results, with various symptoms that often have no
correspondence to the bug itself.

DoDi

Gottfried Helms

unread,
Feb 5, 2005, 6:57:08 AM2/5/05
to
Hi Dodi -

> Most probably the reason is a lack of memory, what may be cured by assigning
> more memory to the richedit control, as already posted. The control also may
> catch an according OS exception somewhere else, and throw an equivalent

some misunderstandings I think.
It has nothing to do with memory or so.
See my test-environment:

-- Form1 -------------------


Richedit1

Button1
-----------------------------

Pushing as much as wanted stuff into Richedit1 by clicking Button1
is no problem, I can push 15 MB or 30 MB *without any problem*.

Now I "upgrade" my application. I add ActionMainMenubar1

-- Form2 -------------------
ActionMainMenubar1


Richedit1

Button1
-----------------------------


Now I cannot push more than some 20 Kb into richedit1.
I did not change my available ram of 128 MB, btw. But now I'm getting
"EOutofresources" messages.

The eOutorfresources does not come from the OS but from
the insert-method of richedit.lines in the delphi-VCL-code:

procedure tricheditstrings.insert(const s:string);
begin
// do the inherited insertion stuff
if oldlength+length(s) <> newlength
then raise eOutOfResources;
end;

That's no OS-message. It's only a message from Delphi-Code, that
something was not ok in the comparision of the expected new length
and the computed new length.

A deeper analysis shows, that with one simple deal I can
prevent the eOutofResources - message: Borland encapsulates MS-richedit
into tRichedit and adds a procedure, which is then hooked into the application-
event-loop.

The tActionmainmenubar does the same. So form1 without and form2 with
Actionmainmenubar1 look like


-- Form1---------------------------- ---- Form2-----------------------
ActionMainMenubar1
Hook into ApplEventLoop

Richedit1 Richedit1
Hook into ApplEventloop Hook into ApplEventLoop

Button1 Button1
------------------------------------- ----------------------------------

Form1: arbitrary capacity of Richedit1 Form2 : Richedit1 partially blocked

If I simply "unhook" the actionmainmenubar-hook temporarily before
inserting of lines, and rehook it again after that insertion, no memory-problem,
eOutofresources etc occurs, everything runs fine. I even need not remove the
Actionmainmenubar.

procedure Button1.Onclick(sender:tobject);
begin
PushLines(My80KBstring);
end;

In Form1 this works, and I can fill up my physical ram with up to
128 MB lines into the richedit.

In Form2 this does not work; richedit1 accepts each time only different
broken pieces of My80KbString. If I finally get it up to 32767 lines, then
the outofresources-msg disappear, but the inserting is still not correct
(though far better, differences of only some bytes occur).


Now if I unhook and rehook the Actionmainmenubar-hook:

procedure Button1.Onclick(sender:tobject);
begin
AMMB_DisableMenuHook;
PushLines(My80KBstring);
AMMB_EnableMenuHook;
end;

I have - oh wonder - all my 128 MB available.

Again: there is no reason, that physical or OS-memory should play any role in
that problem. We deal with only 80 KB here and about 1600 lines of 100 Chars.

If I monitor the ActionMainmenubar-hook I get a lot of windows-msgs, when
adding richedit1.lines. That is the reason why I supposed, that the richedit1-hook
and the Actionmainmenubar-hook may possibly interfere or even call them
recursively.

That has nothing to do with OS-resources or memory. The only OS-dependency
may be the maximal size of the application-event-queue. But that could
be tested on another OS and simply adding more lines into the richedit
with one click on button1.


2) ---------------


>
> The correspondence to line numbers <32767 indicates an bug to me, where higher
> line numbers may be treated erroneously as negative numbers, which are handled
> differently, most probably are not handled at all. The error may also occur for

The lines-property stems from Delphi, I know. That is exactly the reason,
why I suspect the error at Borlands and not at microsoft, since the second
part of the error is related to the linenumber-property in exactly the
way as you described.


---

But I'm tired of explaining things repeatedly without new information.

So for my part I leave at it is, luckily I'm not heavily depending
on borlands-delphi-system. I still would like to know, whether this problem
is resolved under D2005, since in D7 it is still present, as I read by
a contributor in d.c.l.d.m. Richedit & Actionmainmenubar seems to me
a very common combination in Delphi-apps on the market, and thus I wanted
to inform a greater community of potential developers.

So, for that, many thanx for your input, anyway -

Gottfried

Am 05.02.05 04:59 schrieb VBDis:

> Im Artikel <cttiad$jnm$04$1...@news.t-online.com>, Gottfried Helms
> <he...@uni-kassel.de> schreibt:
>
>
>>Only the *reason* why some lines could not be added could
>>be caused by some OS-shortages, since each line-adding seems
>>to create a windows-message; and the implemention of the
>>richedit may install some type of recursion - don't know.

(...)

0 new messages