Images and links
Inserting images
// Insert an image from a file at the cursor position
RichEditor1.InsertImage('photo.png');
// Insert from a bitmap
var bmp: TBitmap;
begin
bmp := TBitmap.Create;
try
bmp.LoadFromFile('photo.png');
RichEditor1.InsertImage(bmp);
finally
bmp.Free;
end;
end;
Graphic selection handles
When a user clicks an embedded image, selection handles appear around it. The handle appearance is controlled by GraphicSelection:
| Property | Description |
|---|---|
GraphicSelection.Color |
Background color of the selection grip squares |
GraphicSelection.BorderColor |
Border color of the grip squares |
GraphicSelection.Style |
gsRect for square handles, gsCircle for round handles |
RichEditor1.GraphicSelection.Style := gsCircle;
RichEditor1.GraphicSelection.Color := gcDodgerBlue;
RichEditor1.GraphicSelection.BorderColor := gcWhite;
Inserting hyperlinks
// Insert clickable link text at the cursor position. The display text is
// the first argument, the target URL the second.
RichEditor1.AddHyperlink('TMS Software', 'https://www.tmssoftware.com');
// Turn an existing selection into a hyperlink instead
RichEditor1.SetSelectionHyperlink('https://www.tmssoftware.com');
Auto-open URLs
URLOpen decides which gesture opens a link in the default browser: uoCtrl (the default) requires Ctrl+click, uoClick opens on a plain click, uoAlt on Alt+click, and uoNone never opens the link. URLAuto (uAuto by default) controls whether typed or pasted URLs are auto-detected and turned into links at all:
RichEditor1.URLOpen := uoClick;
RichEditor1.URLAuto := uAuto;
To handle link clicks yourself, assign OnClickHyperlink:
procedure TForm1.RichEditor1ClickHyperlink(Sender: TObject; URL: string);
begin
// Custom handling instead of auto-open
ShowMessage('Link clicked: ' + URL);
end;
Custom drawing the page background and graphic placeholders
Two hooks let you paint into the content area yourself. Use them when the
document needs something the element model cannot express - a watermark, a
printed-form background, or a placeholder whose visual is computed at runtime
rather than stored in the document. For anything that is genuinely part of the
content, insert a real element (InsertImage, AddHyperlink) instead, so it
survives a save/load round trip.
| Event | Signature | Fires |
|---|---|---|
OnDrawBackground |
(Sender: TObject; ACanvas: TCanvas; ARect: TRect) |
Immediately after the page rectangle has been filled, before any element is painted. |
OnDrawGraphic |
(Sender: TObject; ACanvas: TCanvas; ARect: TRect; AID: string) |
To paint a TGraphicElement placeholder, identified by the AID string it was inserted with. |
procedure TForm1.RichEditorDrawBackground(Sender: TObject; ACanvas: TCanvas;
ARect: TRect);
var
r: TRectF;
begin
// ARect is the page rectangle the editor has just filled: client
// coordinates, already reduced by PageMargin and shifted by the scroll
// offset. Derive everything from it rather than from the control bounds.
r := RectF(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
ACanvas.Fill.Kind := TBrushKind.Solid;
ACanvas.Fill.Color := $22C00000;
ACanvas.Font.Size := 48;
ACanvas.FillText(r, 'DRAFT', False, 1, [],
TTextAlign.Center, TTextAlign.Center);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TMSFNCRichEditor1.OnDrawBackground := RichEditorDrawBackground;
TMSFNCRichEditor1.AddText('Quarterly report');
TMSFNCRichEditor1.AddLineBreak;
// A graphic element is a sized placeholder identified by a string ID; the
// document stores the ID, not a bitmap.
TMSFNCRichEditor1.InsertGraphic('signature', 120, 40);
end;
A graphic placeholder is created with InsertGraphic(AID, AWidth, AHeight).
The document stores only the identifier and the reserved size, so the same
document can render a different visual per application - a signature, a chart, a
barcode - without embedding a bitmap.
Pitfalls
OnDrawBackgroundfires before the elements are drawn, so whatever you paint there sits behind the text. There is no matching after-content hook, so a foreground overlay is not available through this event.- Painting goes to the editor's offscreen buffer, not directly to the screen, and the buffer is not redrawn for a caret blink alone. Do not rely on the event as a timer.
ARectalready accounts forPageMarginand the vertical scroll offset, and it changes as the user scrolls. Derive positions fromARectrather than from the control's own bounds.- The handler runs on every repaint. Keep it allocation-free; loading a bitmap from disk inside it will make scrolling stutter.
OnDrawGraphicis not raised on FMX targets. The FMX element painter currently renders everyTGraphicElementas the red placeholder cross without consulting the event, so on FMX use an inserted image element for runtime visuals rather than a graphic placeholder.
Combining inline images and hyperlinks in a document
RichEditor1.AddText('See the product page: ');
RichEditor1.AddHyperlink('TMS Software', 'https://www.tmssoftware.com');
RichEditor1.AddLineBreak;
RichEditor1.AddLineBreak;
RichEditor1.InsertImage('banner.png');
Related API
TTMSFNCRichEditor—InsertImage,AddHyperlink,SetSelectionHyperlink,URLAuto,URLOpen,GraphicSelection,OnClickHyperlink,OnDrawBackground,OnDrawGraphic
See also
- Editing and formatting — text and paragraph formatting
- Import and export — save content with images as HTML or PDF