问题
I have a TMemo in which I tried to load text but I get this error: "Text exceeds memo capacity". The code is this: Memo1.Lines.LoadFromFile(s) What is the limit for TMemo under Delphi 7/Win 7? I knew there was a 64KB limit but under Win95/98.
Note: This error is a screenshot sent by a user. I can successfully load large files (5-10 MB).
Update:
I got a new bug report this time at this line:
procedure TCLog.Add (s: string; Cl: TColor);
begin
SelStart:= Length(Text);
SelAttributes.Color:= Cl;
S:= GenerateString(Indent, ' ')+ S;
TRY
Lines.Add(s); <------------------------ HERE
EXCEPT
on E: Exception DO
begin
MesajError('Cannot store string '+ s);
raise; // re-raise the currently caught exception
end;
END;
if AutoScroll
then LogScroll;
end;
回答1:
A TMemo is a wrapper around the Windows "Edit Control"; the answers to this question explain how to find out the maximum length you can store in it, and how to influence that length.
--jeroen
回答2:
The exception is raised in TMemoStrings.SetTextStr procedure in 'stdctrls.pas', in response to a failing WM_SETTEXT message sent to the Memo. VCL looks to the return of 'SendMessage' and if it's '0' throws the exception. There's really no way to tell the actual reason of the failing, as you can see from the documentation only special error codes are for list boxes and combo boxes.
If the user can consistently reproduce the error, you might consider sending him a special build that wraps the 'LoadFromFile' between 'SetLastError'/'GetLastError' calls.
edit: I wondered what would GetLastError tell if I pushed the practical limit of setting text to a Memo (as opposed to the theoretical limit Jeroen's answer refers to).
var
s: array [0.. 1073741823] of Char;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
FillChar(s[0], Length(s) - 1, Ord('a'));
// without line breaks 'SendMessage' takes forever to return
for i := 1 to Length(s) - 1 do
if i mod 50 = 0 then begin
s[i - 1] := #13;
s[i] := #10;
end;
s[Length(s) - 1] := #0;
SetLastError(0);
try
if SendMessage(Memo1.Handle, WM_SETTEXT, 0, Longint(@s[0])) = 0 then
raise Exception.Create('set text fail');
except
ShowMessage(SysErrorMessage(GetLastError));
end;
end;
The limit would change depending on specific conditions, but here, the above pops "Not enough storage is available to process this command". (With f.i. half of that (0.5GB) there's no problem setting the text.)
回答3:
If I might suggest you just take the TMemo out and put a RichEdit in its place, or an editor like SynEdit.
Then you won't have to find out why the MS Common Control that the TMemo is wrapping happens to fail at your client's site in this random and annoying way.
回答4:
I have tested TMemo with a String of 500,000 characters and it worked:
procedure TForm5.Button1Click(Sender: TObject);
VAR s: string;
begin
s:= GenerateString(1000000, 'x');
Memo1.Text:= s;
end;
It takes 20 seconds though.
Later I have replaced the TEdit with a TRichEdit and I had further problems. In the end I realized that the culprit was a string that contained the #0 character. Looks like TRichEdit screws up when it encounter this character.
来源:https://stackoverflow.com/questions/4866400/text-exceeds-memo-capacity-error