我有一个TMemo,其中我尝试加载文本,但我收到此错误:“文本超出备忘录容量”。代码是这样的:Memo1.Lines.LoadFromFile(s) Delphi 7 / Win 7下TMemo的限制是什么?我知道有64KB的限制,但在Win95 / 98下。
注意:此错误是用户发送的屏幕截图。我可以成功加载大文件(5-10 MB)。
更新
这次我收到了一个新的错误报告:
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;
答案 0 :(得分:2)
在'stdctrls.pas'中的TMemoStrings.SetTextStr
过程中引发异常,以响应发送到备忘录的失败的WM_SETTEXT
消息。 VCL查看“SendMessage”的返回值,如果它为“0”则抛出异常。实际上没有办法说明失败的真正原因,正如您从文档中看到的那样,只有特殊的错误代码用于列表框和组合框。
如果用户可以一致地重现错误,您可以考虑向他发送一个特殊版本,将“LoadFromFile”包装在“SetLastError”/“GetLastError”调用之间。
编辑:我想知道如果我将设置文字的实际限制推到备忘录(而不是理论上的限制Jeroen's answer} GetLastError
会告诉我什么指)。
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;
限制将根据具体情况而变化,但在此处,上述弹出“没有足够的存储空间可用于处理此命令”。 (f.i。的一半(0.5GB)设置文本没有问题。)
答案 1 :(得分:2)
TMemo是Windows“编辑控件”的包装器; this question的答案解释了如何找出可存储在其中的最大长度,以及如何影响该长度。
- 的Jeroen
答案 2 :(得分:1)
如果我建议您只需要将TMemo取出并放置RichEdit,或者像SynEdit这样的编辑器。
然后,您将不必了解为什么TMemo包装的MS公共控制在您的客户端站点以这种随机和烦人的方式失败。
答案 3 :(得分:0)
我已经使用500,000个字符的字符串测试了TMemo并且它有效:
procedure TForm5.Button1Click(Sender: TObject);
VAR s: string;
begin
s:= GenerateString(1000000, 'x');
Memo1.Text:= s;
end;
虽然需要20秒。
后来我用TRichEdit替换了TEdit,我还有其他问题。最后我意识到罪魁祸首是一个包含#0字符的字符串。看起来TRichEdit遇到这个角色时会搞砸。