Editing and formatting
Text selection
// Select all
RichEditor1.SelectAll;
// Select a range (character offset, length)
RichEditor1.Select(10, 5);
// Deselect
RichEditor1.ClearSelection;
Character formatting
Apply formatting to the current selection or the cursor position (affects new typing):
| Property | Type | Description |
|---|---|---|
Bold |
Boolean |
Bold text |
Italic |
Boolean |
Italic text |
Underline |
Boolean |
Underline |
StrikeThrough |
Boolean |
Strikethrough |
SuperScript |
Boolean |
Superscript |
SubScript |
Boolean |
Subscript |
FontName |
String |
Font family |
FontSize |
Single |
Font size in points |
FontColor |
TAlphaColor |
Text color |
// Make selected text bold and red
RichEditor1.Bold := True;
RichEditor1.FontColor := gcRed;
Reading the same properties returns the formatting at the cursor or in the selection.
Paragraph formatting
| Property | Type | Description |
|---|---|---|
HorizontalTextAlign |
TTMSFNCGraphicsTextAlign |
gtaLeading, gtaCenter, gtaTrailing, gtaJustify |
LineSpacing |
Single |
Line spacing multiplier |
RichEditor1.HorizontalTextAlign := gtaCenter;
Lists
// Toggle ordered (numbered) list
RichEditor1.OrderedList := True;
// Toggle unordered (bulleted) list
RichEditor1.UnorderedList := True;
Indentation
RichEditor1.Indent; // increase indent
RichEditor1.Outdent; // decrease indent
Undo and redo
if RichEditor1.CanUndo then RichEditor1.Undo;
if RichEditor1.CanRedo then RichEditor1.Redo;
Inserting text
// Insert at cursor position
RichEditor1.InsertText('Hello, world!');
Reading content
// Plain text
var plain := RichEditor1.PlainText;
// HTML
var html := RichEditor1.HTML;
Clipboard: cut, copy, and paste
The editor exchanges more than plain text with the clipboard: a copy carries the selection as an internal rich-text stream, as RTF, and as plain text at the same time, so a paste back into the editor keeps its formatting while a paste into a plain-text field still works. Reach for the clipboard events when the document must not accept everything a user might paste - stripping tabs out of spreadsheet text, or refusing a multi-megabyte screenshot.
| Member | Purpose |
|---|---|
CopyToClipboard |
Copies the selection in every format the editor produces. |
CutToClipboard |
Copies the selection, then deletes it. A selected image is copied as a picture. |
PasteFromClipboard |
Pastes the clipboard content over the selection. Returns the plain text that was inserted. |
ClipboardHasContent |
True when the clipboard holds a format the editor can paste - use it to enable a Paste command. |
ClipboardFormats |
The TClipboardFormat set (cfRTE, cfRTF, cfText, cfHTML, cfBMP, cfFile) the editor is willing to accept. |
CopyRTFToClipboard, CopyHTMLToClipboard |
Place only the RTF or only the HTML representation on the clipboard. |
| Event | Signature |
|---|---|
OnPasteText |
(Sender: TObject; var AText: string; var Allow: boolean) |
OnPasteBitmap |
(Sender: TObject; ABitmap: TTMSFNCBitmap; var Allow: boolean) |
OnPasteFormattedText |
(Sender: TObject; AStream: TStream) |
procedure TForm1.RichEditorPasteText(Sender: TObject; var AText: string;
var Allow: boolean);
begin
// AText is a var parameter, so rewriting it here changes what is inserted.
AText := StringReplace(AText, #9, ' ', [rfReplaceAll]);
Allow := Trim(AText) <> '';
end;
procedure TForm1.RichEditorPasteBitmap(Sender: TObject;
ABitmap: TTMSFNCBitmap; var Allow: boolean);
begin
// Keep an oversized screenshot out of the document rather than scaling it
// after the fact.
Allow := (ABitmap.Width <= 1600) and (ABitmap.Height <= 1600);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TMSFNCRichEditor1.OnPasteText := RichEditorPasteText;
TMSFNCRichEditor1.OnPasteBitmap := RichEditorPasteBitmap;
// Accept rich text and plain text on paste, but never a bitmap.
TMSFNCRichEditor1.ClipboardFormats := [cfRTF, cfText];
end;
procedure TForm1.PasteButtonClick(Sender: TObject);
var
s: string;
begin
// Use ClipboardHasContent to drive the enabled state of a Paste command;
// it reports whether any pastable format is present at all.
if not TMSFNCRichEditor1.ClipboardHasContent then
Exit;
// The result is the plain text that was inserted. It is empty when the
// clipboard delivered rich text or a bitmap instead.
s := TMSFNCRichEditor1.PasteFromClipboard;
StatusLabel.Text := Format('Pasted %d characters of plain text', [Length(s)]);
end;
procedure TForm1.CopyButtonClick(Sender: TObject);
begin
if TMSFNCRichEditor1.HasSelection then
TMSFNCRichEditor1.CopyToClipboard
else
TMSFNCRichEditor1.SelectAll;
end;
procedure TForm1.CutButtonClick(Sender: TObject);
begin
if TMSFNCRichEditor1.HasSelection then
TMSFNCRichEditor1.CutToClipboard;
end;
Paste order and pitfalls
PasteFromClipboard walks the available formats in a fixed order - rich-text
stream, then RTF, then bitmap, then plain text - and inserts the first match in
each group it is allowed to use. Four consequences are worth knowing:
- Rich text wins over plain text. The plain-text branch is skipped once a
rich-text or RTF paste succeeded, so
OnPasteTextdoes not fire for a formatted paste. A sanitiser that only lives inOnPasteTextis bypassed by any clipboard that also carries RTF; removecfRTFfromClipboardFormatsif plain text must always be the route in. - A bitmap is not mutually exclusive. The bitmap branch is not skipped by a preceding rich-text paste, so a clipboard holding both RTF and an image can insert both in one call.
- The return value only reflects the plain-text branch. It is an empty string after a formatted or bitmap paste, which is not an error.
- On FMX targets
ClipboardFormatsgates pasting only. A copy always publishes plain text, RTF, and (except on Android) the internal rich-text stream regardless of the set, so narrowingClipboardFormatsdoes not reduce what other applications see when they paste from your document.
Combining programmatic editing, formatting, and content retrieval
RichEditor1.SelectAll;
RichEditor1.Delete;
// Heading
RichEditor1.FontSize := 18;
RichEditor1.Bold := True;
RichEditor1.InsertText('Project Report');
RichEditor1.Bold := False;
RichEditor1.FontSize := 12;
RichEditor1.InsertLineBreak;
RichEditor1.InsertLineBreak;
// Paragraph
RichEditor1.HorizontalTextAlign := gtaLeading;
RichEditor1.InsertText(
'This report summarizes the work completed in Q2.');
RichEditor1.InsertLineBreak;
RichEditor1.InsertLineBreak;
// Bulleted list
RichEditor1.UnorderedList := True;
RichEditor1.InsertText('Feature A completed');
RichEditor1.InsertLineBreak;
RichEditor1.InsertText('Feature B in progress');
RichEditor1.InsertLineBreak;
RichEditor1.UnorderedList := False;
Related API
TTMSFNCRichEditor—Bold,Italic,Underline,FontName,FontSize,FontColor,InsertText,SelectAll,Undo,Redo
See also
- Images and links — embed images and insert hyperlinks
- Toolbar — connect the toolbar for interactive formatting