“Text exceeds memo capacity” error

☆樱花仙子☆ 提交于 2020-02-06 04:21:06

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!