Editing and formatting
Text selection
// Select all
RichEditor1.SelectAll;
// Select a range (character offset, length)
RichEditor1.Select(10, 5);
// Deselect
RichEditor1.ClearSelection;
// 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):
| Method | Description |
|---|---|
SetSelectionBold(Boolean) |
Bold text |
SetSelectionItalic(Boolean) |
Italic text |
SetSelectionUnderline(Boolean) |
Underline |
SetSelectionStrikeOut(Boolean) |
Strikethrough |
SetSelectionSuperscript(Boolean) |
Superscript |
SetSelectionSubscript(Boolean) |
Subscript |
SetSelectionFontName(string) |
Font family |
SetSelectionFontSize(Integer) |
Font size in points |
SetSelectionColor(TTMSFNCGraphicsColor) |
Text color |
// Make selected text bold and red
RichEditor1.SetSelectionBold(True);
RichEditor1.SetSelectionColor(gcRed);
// Make selected text bold and red
RichEditor1->SetSelectionBold(true);
RichEditor1->SetSelectionColor(gcRed);
Reading the same properties returns the formatting at the cursor or in the selection.
Paragraph formatting
Alignment is applied through SetSelectionAttribute with a TAlignment value (taLeftJustify, taCenter, taRightJustify). LineSpacing is an Integer property (default 0) that adds spacing between lines.
RichEditor1.SetSelectionAttribute(taCenter);
RichEditor1->SetSelectionAttribute(taCenter);
Lists
SetSelectionBullets applies a bullet or number style to the selected lines, and toggles it off when the caret is already in a list of the same type. Use RemoveSelectionBullets to clear it explicitly.
// Numbered list: btNumber; bulleted list: btCircle, btSquare, btArrow, btTick, btStar
RichEditor1.SetSelectionBullets(btNumber);
RichEditor1.SetSelectionBullets(btCircle);
RichEditor1.RemoveSelectionBullets;
// Numbered list: btNumber; bulleted list: btCircle, btSquare, btArrow, btTick, btStar
RichEditor1->SetSelectionBullets(btNumber);
RichEditor1->SetSelectionBullets(btCircle);
RichEditor1->RemoveSelectionBullets;
Indentation
RichEditor1.SetSelectionIndent(24); // left indent of the selected paragraphs
RichEditor1.SetSelectionIndent(0); // remove the indent
RichEditor1->SetSelectionIndent(24); // left indent of the selected paragraphs
RichEditor1->SetSelectionIndent(0); // remove the indent
Undo and redo
if RichEditor1.CanUndo then RichEditor1.Undo;
if RichEditor1.CanRedo then RichEditor1.Redo;
if (RichEditor1->CanUndo) RichEditor1->Undo;
if (RichEditor1->CanRedo) RichEditor1->Redo;
Inserting text
// Insert at cursor position
RichEditor1.InsertText('Hello, world!');
// Insert at cursor position
RichEditor1->InsertText("Hello, world!");
Reading content
// Plain text
var plain := RichEditor1.PlainText;
// HTML
var html := RichEditor1.HTML;
// 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;
void __fastcall TForm1::RichEditorPasteText(TObject *Sender, System::UnicodeString &AText,
bool &Allow)
{
// AText is a var parameter, so rewriting it here changes what is inserted.
AText = StringReplace(AText, "\t", " ", TReplaceFlags() << rfReplaceAll);
Allow = Trim(AText) != "";
}
void __fastcall TForm1::RichEditorPasteBitmap(TObject *Sender,
TTMSFNCBitmap *ABitmap, bool &Allow)
{
// Keep an oversized screenshot out of the document rather than scaling it
// after the fact.
Allow = (ABitmap->Width <= 1600) && (ABitmap->Height <= 1600);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TMSFNCRichEditor1->OnPasteText = RichEditorPasteText;
TMSFNCRichEditor1->OnPasteBitmap = RichEditorPasteBitmap;
// Accept rich text and plain text on paste, but never a bitmap.
TMSFNCRichEditor1->ClipboardFormats = TClipboardFormats() << TClipboardFormat::cfRTF << TClipboardFormat::cfText;
}
void __fastcall TForm1::PasteButtonClick(TObject *Sender)
{
// Use ClipboardHasContent to drive the enabled state of a Paste command;
// it reports whether any pastable format is present at all.
if (!TMSFNCRichEditor1->ClipboardHasContent())
return;
// The result is the plain text that was inserted. It is empty when the
// clipboard delivered rich text or a bitmap instead.
System::UnicodeString s = TMSFNCRichEditor1->PasteFromClipboard();
StatusLabel->Text = Format("Pasted %d characters of plain text", ARRAYOFCONST((s.Length())));
}
void __fastcall TForm1::CopyButtonClick(TObject *Sender)
{
if (TMSFNCRichEditor1->HasSelection())
TMSFNCRichEditor1->CopyToClipboard();
else
TMSFNCRichEditor1->SelectAll();
}
void __fastcall TForm1::CutButtonClick(TObject *Sender)
{
if (TMSFNCRichEditor1->HasSelection())
TMSFNCRichEditor1->CutToClipboard();
}
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
procedure TForm1.BuildReport;
var
Html: string;
begin
RichEditor1.Clear;
// Centered bold heading
RichEditor1.AddText('Project Report', 18, 'Arial', [TFontStyle.fsBold], taCenter);
RichEditor1.AddLineBreak;
// Left-aligned paragraph
RichEditor1.AddText('This report summarizes the work completed in Q2.', 12, 'Arial', [], taLeftJustify);
// Bulleted list: AddBullet starts a new line and adds the bullet marker
RichEditor1.AddBullet(btCircle);
RichEditor1.AddText('Feature A completed');
RichEditor1.AddBullet(btCircle);
RichEditor1.AddText('Feature B in progress');
// Retrieve the result as HTML
Html := RichEditor1.ContentAsHTML;
end;
void __fastcall TForm1::BuildReport()
{
System::UnicodeString Html;
RichEditor1->Clear();
// Centered bold heading
RichEditor1->AddText("Project Report", 18, "Arial", TFontStyles() << TFontStyle::fsBold, taCenter);
RichEditor1->AddLineBreak();
// Left-aligned paragraph
RichEditor1->AddText("This report summarizes the work completed in Q2.", 12, "Arial", TFontStyles(), taLeftJustify);
// Bulleted list: AddBullet starts a new line and adds the bullet marker
RichEditor1->AddBullet(Fmx::Tmsfncricheditorbase::btCircle);
RichEditor1->AddText("Feature A completed");
RichEditor1->AddBullet(Fmx::Tmsfncricheditorbase::btCircle);
RichEditor1->AddText("Feature B in progress");
// Retrieve the result as HTML
Html = RichEditor1->ContentAsHTML();
}
Related API
TTMSFNCRichEditor—SetSelectionBold,SetSelectionItalic,SetSelectionUnderline,SetSelectionFontName,SetSelectionFontSize,SetSelectionColor,InsertText,SelectAll,Undo,Redo
See also
- Images and links — embed images and insert hyperlinks
- Toolbar — connect the toolbar for interactive formatting