TRichEdit has the properties: EnableURLs
and ShowURLHint
. EnableURLs automatically converts Internet URLs like e.g. http://www.example.com to hyperlinks.
With the code below, I tried to achieve the same functionality with email addresses. This works only visually:
Question: But how can I automatically achieve the name@somewhere.com hyperlink functionality (crHandPoint cursor and OnURLClick event handler) when clicking on the email address?
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;
type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
Label1: TLabel;
procedure RichEdit1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
System.RegularExpressions;
procedure DetectAndLinkifyEmailsAndURLs(RichEdit: Vcl.ComCtrls.TRichEdit);
var
Match: System.RegularExpressions.TMatch;
EmailPattern, URLPattern: string;
LineIndex, LineStart, StartPos, SelLength: Integer;
LineText: string;
PrevSelStart, PrevSelLength: Integer;
begin
EmailPattern := '\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b';
URLPattern := '\b(http|https)://[^\s]+';
// Disable redraw to avoid flicker
SendMessage(RichEdit.Handle, WM_SETREDRAW, WPARAM(False), 0);
try
// Save user selection
PrevSelStart := RichEdit.SelStart;
PrevSelLength := RichEdit.SelLength;
// Reset all formatting to default for the entire text
RichEdit.SelectAll;
RichEdit.SelAttributes.Color := Vcl.Graphics.clWindowText;
RichEdit.SelAttributes.Style := [];
// Process line by line
for LineIndex := 0 to RichEdit.Lines.Count - 1 do
begin
LineText := RichEdit.Lines[LineIndex];
LineStart := RichEdit.Perform(EM_LINEINDEX, LineIndex, 0); // Get line start position
// Format email addresses in the line
Match := System.RegularExpressions.TRegEx.Match(LineText, EmailPattern, [System.RegularExpressions.roIgnoreCase]);
while Match.Success do
begin
StartPos := LineStart + Match.Index - 1;
SelLength := Match.Length;
RichEdit.SelStart := StartPos;
RichEdit.SelLength := SelLength;
RichEdit.SelAttributes.Color := Vcl.Graphics.clBlue;
RichEdit.SelAttributes.Style := [Vcl.Graphics.fsUnderline];
Match := Match.NextMatch;
end;
// Format URLs in the line
Match := System.RegularExpressions.TRegEx.Match(LineText, URLPattern, [System.RegularExpressions.roIgnoreCase]);
while Match.Success do
begin
StartPos := LineStart + Match.Index - 1;
SelLength := Match.Length;
RichEdit.SelStart := StartPos;
RichEdit.SelLength := SelLength;
RichEdit.SelAttributes.Color := Vcl.Graphics.clBlue;
RichEdit.SelAttributes.Style := [Vcl.Graphics.fsUnderline];
Match := Match.NextMatch;
end;
end;
// Restore user selection
RichEdit.SelStart := PrevSelStart;
RichEdit.SelLength := PrevSelLength;
// Ensure the current selection uses default formatting
if (PrevSelStart >= 0) and (PrevSelLength = 0) then
begin
RichEdit.SelAttributes.Color := Vcl.Graphics.clWindowText;
RichEdit.SelAttributes.Style := [];
end;
finally
// Re-enable redraw
SendMessage(RichEdit.Handle, WM_SETREDRAW, WPARAM(True), 0);
RichEdit.Invalidate; // Refresh to reflect changes
end;
end;
procedure TForm1.RichEdit1Click(Sender: TObject);
begin
DetectAndLinkifyEmailsAndURLs(RichEdit1);
end;
end.
The Auto URL Detection feature supports email addresses. You can simply prefix them with the mailto:
url scheme.
If you don't want to do that, then on Windows 8 and later, you can manually send an EM_AUTOURLDETECT
message to the TRichEdit
window, specifying the AURL_ENABLEEMAILADDR
flag in the wParam
parameter.
Otherwise, you will have to enable the hyperlinks manually. Select the desired text and apply the CFE_LINK
format style to it, which you can do via the TRichEdit.SelAttributes.Link
property (if your Delphi version supports that) or the EM_SETCHARFORMAT
message.