1

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;
Gabriel
  • 20,797
  • 27
  • 159
  • 293
  • 4
    Although *you* can load a 10 MB file, how big a file was the *customer* trying to load? – Rob Kennedy Feb 01 '11 at 19:08
  • 1
    Not sure this is related to your problem, but check http://www.zuggsoft.com/forums/viewtopic.php?t=34572 – Guillem Vicens Feb 01 '11 at 21:05
  • Thanks Guillem. The user says that it did not resided the window at any point. But anyway, the page to which you pointed is really interesting. I think I should try that solution just in case. – Gabriel Feb 09 '11 at 11:51
  • @Rob - It NEVER EVER goes over 1MB. It should be around 10KB-20KB. – Gabriel Feb 09 '11 at 13:08
  • Regarding your edit, is 'lines' a `TRichEdit.Lines`? What error do you get? What makes you think that the first report and the second report are related? – Sertac Akyuz Feb 09 '11 at 18:53

4 Answers4

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.)

Community
  • 1
  • 1
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
2

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

Community
  • 1
  • 1
Jeroen Wiert Pluimers
  • 23,965
  • 9
  • 74
  • 154
1

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.

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • I see that SysEdit is 'preview' which sounds to me 'less than beta'. Did you use it? It is stable? – Gabriel Feb 09 '11 at 12:11
0

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.

Gabriel
  • 20,797
  • 27
  • 159
  • 293