Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Memo mit vielen Zeilen wird abgeschnitten


Peter18 - Sa 21.12.13 19:58
Titel: Memo mit vielen Zeilen wird abgeschnitten
Ein freundliches Hallo an alle,

ich habe ein Memo-Feld probeweise mit sehr viel Text gefüllt, den ich dann an die Mapi weiterleiten wollte. Der Neue String wurde irgendwo abgeschnitten. Die Stringliste "Memo1.Lines" ist noch vollständig! Da meine Unterlagen zu Dephi 4 sehr bescheiden sind und nichts zu dem Thema hergeben, stelle ich die Frage hier zu Diskussion.

Delphi-Quelltext
1:
StrNew(PChar( Memo1.Lines.Text ));                    

Ist der Heap zu klein oder woran kann es liegen, dass der resultierende String abgeschnitten wird? Wie läst sich das Problem lösen?

Grüße von der Nordsee

Peter


Mathematiker - Sa 21.12.13 20:21

Hallo,
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
ich habe ein Memo-Feld probeweise mit sehr viel Text gefüllt

Wie viel ist denn "sehr viel Text"?
In Deinem Profil steht zwar Delphi 4, aber welches Betriebssystem ist es denn?

Beste Grüße
Mathematiker


Tranx - Sa 21.12.13 21:31

Die Funktion StrNew erzeuggt nur einen Zeiger auf den abgelegten String. Sicher ist die maximale Größe des Strings auf die Heapgröße (-5 Bytes) beschränkt. Wenn dieses, was da möglich ist, zu klein für Deinen Text ist, versuche doch mal unter Projektoptionen -> Linker die maximale Stackgröße zu erhöhen. Vielleicht hilft das.

Aber wofür benötigst Du denn eine Kopie des Textes auf dem Heap? Du könntest ja die Text-Funktion des Memos selber nehmen. Oder willst Du dieses sozusagen als Backup haben, das nach Veränderung des Memotextes gegebenenfalls zurückgeladen werden kann?


jaenicke - Sa 21.12.13 21:47

Hast du es einmal ohne Memo ausprobiert? Mit TStringList z.B. bzw. am besten direkt mit einem reinen String? Denn eine visuelle Komponente zu nehmen um so etwas zu testen ist wenig sinnvoll. ;-)


Peter18 - So 22.12.13 12:48

Hallo an alle,

dank Euch für die Antworten. Das ganze war ein Testprogramm um die Mapi auszuprobieren. Memo bot die Möglichkeit für erste Versuche Text vorzugeben und zur Laufzeit zu verändern. Um zu sehen, ob es auch mit größeren Textmengen funktioniert habe ich eine Textdatei über die Zwischenablage in das Memo-Feld kopiert und stellte fest, dass nicht alles in der Mail gelandet ist. Dabei zeigte es sich, dass die Stringliste "Memo1.Lines" vollständig war. Mit "Memo1.Lines.Text" war jedoch ein Teil des Textes abgeschnitten.
Auch die folgende Funktion lieferte das gleiche Ergebnis.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function StrLstToStr( Lst : TStrings ): PChar;
var
  I, J, L, O : Cardinal;
  S          : String;

begin
  L := Lst.Count * 2 + 1;
  for I := 0 to Lst.Count-1 do L := L + Length( Lst.Strings[ I ] );
  Result := StrAlloc( L );
  O      := 0;
  for I := 0 to Lst.Count-1 do
  begin
    S := Lst.Strings[ I ] + Chr(10)+Chr(13);
    for J := 1 to Length( S ) do     
    begin
      Result[O] := S[ J ];
      O         := O + 1;
    end;                                                  
  end;
end;

Da man zur Entwicklungszeit nicht weiß wie groß eine Mail wird, macht es wenig Sinn die Stackgröße zu erhöhen, eine Grenze bleibt dann ja trotzdem. Eine Lösung die von Stack und Heap unabhängig ist wäre also gut.

Grüße von der Nordsee

Peter


jaenicke - So 22.12.13 15:03

Vielleicht kann die API schlicht nicht mehr. Um das zu testen würde ich einfach mal die Textdatei mit einem TStringStream direkt in einen String einlesen. Das ist nicht größenbegrenzt (außer durch den RAM). Oder gleich einen zufallsgenerierten String mit definiertem Endzeichen zur Erkennung nehmen.


Peter18 - So 22.12.13 16:06

Hallo jaenicke,

Danke für die Antwort. Das Problem scheint mir nicht bei der API zu liegen, denn "Memo1.Lines" enthielt alle Zeilen, "Memo1.Lines.Text" war abgeschnitten. Mit "StrLstToStr" zähle ich die Zeichen und reserviere entsprechnd Platz, das Ergebnis war jedoch das das gleiche.

Zum Veranschaulichen habe ich gerade ein Testprogramm erstellt.


Delphi-Quelltext
1:
Memo2.Lines.Add( Memo1.Lines.Text );                    


Hier zeigte sich der Effekt nicht. Mit "Auswerten/Ändern" war aber genau an der selben Stelle Schluß, an der auch die Mail zu Ende war. Sieht so aus, als ob das Problem an anderer Stelle zu suchen ist.

Grüße von der Nordsee

Peter


Peter18 - So 22.12.13 17:38

Ein freundliches Hallo an alle,

weitere Experimente habe zu einem Ergebnis geführt: "StrNew" ist bei der Mapi nicht notwendig (war auch etwas seltsam aber in Beispielen enthalten). Offenbar ist tatsächlich der Heap der Übeltäter. "Auswerten/Ändern" speichert anscheinend seine Daten dort, genauso wie "StrNew". Nach Entfernen der Funktion sind die Daten vollständig in der Mail.

Grüße von der Nordsee

Peter