Say you want to copy the formatted text of one rich edit control to another. Dest.Lines.Assign(Source.Lines) won’t work, since while the text will be copied, it will be unformatted. What you need to do, then, is to stream out from the source text to a temporary memory stream before streaming in to the destination control:
type TCustomRichEditAccess = class(TCustomRichEdit); procedure CopyRichText(Source, Dest: TCustomRichEdit); var Temp: TMemoryStream; begin Temp := TMemoryStream.Create; try TCustomRichEditAccess(Source).Lines.SaveToStream(Temp); Temp.Position := 0; TCustomRichEditAccess(Dest).Lines.LoadFromStream(Temp); finally Temp.Free; end; end;
There is one problem with this code however — if you’re using the JVCL’s rich edit control it won’t work, since this class does not descend from TCustomRichEdit. Because of this, RTTI needs to be used if you wish to be able to copy to and from a mixture of JVCL and ‘standard’ rich edit controls:
procedure CopyRichText(Source, Dest: TCustomMemo); function GetRichLines(RichEdit: TCustomMemo): TStrings; begin Result := GetObjectProp(RichEdit, 'Lines', TStrings) as TStrings; if (Result = nil) or Result.ClassNameIs('TMemoStrings') then raise Exception.Create('Lines property not found on object'); end; var Temp: TMemoryStream; begin Temp := TMemoryStream.Create; try GetRichLines(Source).SaveToStream(Temp); Temp.Position := 0; GetRichLines(Dest).LoadFromStream(Temp); finally Temp.Free; end; end;
The check for TMemoStrings is because TCustomEdit, the immediate ancestor to both TCustomRichEdit and the the JVCL equivalent, exposes a Lines property with public visibility that always streams out plain text – what we want instead, then, is the Lines property on the rich edit class itself.