... es geht noch einfacher, besser und universeller.
Ein'\page' oder '\pagebb' steht immer irgendwo mit anderen Steuerzeichen vor dem Text, der auf die nächste Seite soll.
Ich ersetze nun einfach diese Steuerreichen mit einem Text (hier: '|NEWPAGE|'), der auch anschließend im RTF lesbar am Anfang der Zeike steht.
Anschließend loope ich alle Zeilen im Richedit und prüfe auf eben diesen Text.
Sofern vorhanden, wird ein Seitenwechsel vermerkt und der Text einfach wieder aus der Richedit-Zeile gelöscht.
Das funktioniert 1A - egal ob der Text plain oder irgendwie Formatiert ist, Umlaute oder Sonderzeichen hat.
Delphi-Quellcode:
///-----------------------------------------------------------------------------
procedure TForm1.Search4Pages(Datei : string);
var
SS : TStringStream;
MS : TMemoryStream;
RTFplain : ANSIString; // shoulb be NOT a normal (wide) String !!!
i, LineFrom : integer;
begin
SS := TStringStream.Create('');
MS := TMemoryStream.Create;
ClearPagelList;
Memo.Clear;
RE_SRC.Clear;
RE_PAGE.Clear;
// ... load the file (or stream)
SS.LoadFromFile(Datei);
SetLength(RTFplain, SS.Size);
SS.Read(RTFplain[1], SS.Size); // or SS.ReadBuffer !?
RTFplain := StringReplace(RTFplain, '\pagebb', ' |NEWPAGE|', [rfReplaceAll]);
RTFplain := StringReplace(RTFplain, '\page', ' |NEWPAGE|', [rfReplaceAll]);
MS.Position := 0;
MS.WriteBuffer(RTFplain[1],Length(RTFplain));
MS.Position := 0;
RE_SRC.Lines.LoadFromStream(MS);
SS.Free; // no longer necessary
MS.Free; // no longer necessary
// ... now loop through (displayed) lines, recognize FormFeed and delete PlaceHolder
LineFrom := 0;
for i := 0 to RE_SRC.Lines.Count - 1 do
begin
RE_SRC.Lines.BeginUpdate;
if Pos('|NEWPAGE|', RE_SRC.Lines[i]) > 0 then
begin
RE_SRC.Lines[i] := StringReplace(RE_SRC.Lines[i], '|NEWPAGE|', '', []); // [rfReplaceAll]);
AddPage2List(LineFrom, i - 1); // Add Page to list:
LineFrom := i; // LineTo + 1;
end;
RE_SRC.Lines.EndUpdate;
end;
AddPage2List(LineFrom, RE_SRC.Lines.Count - 1);
end;
Die procedure für die zu druckenden Seiten hab ich nun auch korrigiert/ergänzt:
Delphi-Quellcode:
// -----------------------------------------------------------------------------
// PageFrom: Min = 1, Max = FPageList.Count
// PageTo: Min = PageFrom, Max = FPageList.Count
procedure TForm1.PrepRTFtoPrint(PageFrom, PageTo : integer; All : boolean);
var
i, ii, LF, LT : integer;
MS : TMemoryStream;
begin
if (FPageList.Count < 1) then exit; // no page to print
if All then // print all pages ...
begin
PageFrom := 1;
PageTo := FPageList.Count;
end;
if (PageFrom < 0) then exit; // range to low
if (PageFrom > FPageList.Count) then exit; // range to high
if (PageTo < PageFrom) then exit; // range to low
if (PageTo > FPageList.Count) then exit; // range to high
// ... print valid pages
for i := PageFrom to PageTo do
begin
LF := PRTFPageData(FPageList[i - 1]).LFrom;
LT := PRTFPageData(FPageList[i - 1]).LTo;
Memo.Lines.Add('... Printing page ' + inttostr(i) +
' - Line ' + inttostr(LF) +
' to ' + inttostr(LT));
// 1st: copy RE_SRC to RE_PAGE
MS := TMemoryStream.Create;
try
RE_SRC.Lines.SaveToStream(MS);
MS.Position := 0;
RE_PAGE.Lines.LoadFromStream(MS) ;
finally
MS.Free;
end;
// 2nd: Loop through all RE_SRC-lines and delete unwanted lines
// !!! walking BACKWARDS through list of lines !!!
for ii := RE_PAGE.Lines.Count - 1 downto 0 do
begin
if (ii < LF) then RE_PAGE.Lines.Delete(ii);
if (ii > LT) then RE_PAGE.Lines.Delete(ii);
end;
// 3rd: call your favourite RTF-printing-service with RE_PAGE....
end;
end;