【问题标题】:"Text exceeds memo capacity" error“文本超出备忘录容量”错误
【发布时间】:2011-06-19 11:30:48
【问题描述】:

我有一个 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;

【问题讨论】:

  • 虽然可以加载一个10 MB的文件,但客户试图加载多大的文件?
  • 不确定这与您的问题有关,但请查看zuggsoft.com/forums/viewtopic.php?t=34572
  • 谢谢吉勒姆。用户说它在任何时候都没有驻留在窗口中。但无论如何,您指向的页面确实很有趣。我想我应该试试这个解决方案以防万一。
  • @Rob - 它永远不会超过 1MB。它应该在 10KB-20KB 左右。
  • 关于您的编辑,'lines' 是 TRichEdit.Lines 吗?你得到什么错误?是什么让您认为第一份报告和第二份报告是相关的?

标签: delphi


【解决方案1】:

在“stdctrls.pas”中的TMemoStrings.SetTextStr 过程中引发异常,以响应发送到备忘录的失败WM_SETTEXT 消息。 VCL 查看“SendMessage”的返回值,如果为“0”则抛出异常。确实没有办法说出失败的实际原因,正如您从文档中看到的那样,只有特殊的错误代码适用于列表框和组合框。

如果用户能够始终如一地重现错误,您可能会考虑向他发送一个特殊的构建,该构建在“SetLastError”/“GetLastError”调用之间包装了“LoadFromFile”。


编辑:我想知道GetLastError 会告诉我如果我将设置文本的实际限制推到备忘录(而不是理论限制Jeroen's answer 指的是)。

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)设置文本没有问题。)

【讨论】:

  • 请注意,GetLastError 相对于wm_SetText 的任何行为未记录
【解决方案2】:

TMemo 是 Windows“编辑控件”的包装; this question 的答案解释了如何找出可以存储在其中的最大长度,以及如何影响该长度。

--杰罗恩

【讨论】:

    【解决方案3】:

    如果我可能建议您将 TMemo 取出并在其位置上放置一个 RichEdit,或者像 SynEdit 这样的编辑器。

    那么您就不必找出为什么 TMemo 包装的 MS 公共控件会以这种随机且令人讨厌的方式在您的客户站点发生故障。

    【讨论】:

    • 我看到 SysEdit 是“预览版”,对我来说听起来“不到 beta”。你用过吗?稳定吗?
    【解决方案4】:

    我已经用 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 在遇到这个角色时会搞砸。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多