I'm using a TRichEdit to edit text. I then use TJvRichEditToHtml to convert the text to HTML which then gets sent as the body of an email via Mailgun. I'd like to include hyperlinks in the text that gets emailed.
Following this SO post, and several other similar ones, I included the code below to insert a formatted hyperlink in the TRichEdit at the insertion point. As expected, that hides the URL and shows the link text as blue, underlined text just as I wanted. i.e. if I insert the url https://stackoverflow.com
, with the text this is a link
, the HTML will contain
HYPERLINK "https://stackoverflow.com/"this is a link
and the Rich text box shows this is a link
all in blue and underlined.
Just before sending the body to Mailgun I then substitute HYPERLINK "
with <a href="
and "
with "
to get the html <a href="https://stackoverflow.com/">this is a link
To identify the end of the link text, so that I can substitute </a>
and close the html hyperlink properly, I added code to append a hidden text token ENDHYPERLINK
after the hypertext link in the TRich edit which I then substitute for </a>
. ie the html before substitution look like HYPERLINK "https://stackoverflow.com/"this is a link ENDHYPERLINK
and after substitution looks like <a href="https://stackoverflow.com/">this is a link</a>
However, when I add this extra text after the hyperlink, although it is correctly invisible in the TRichEdit, the blue underlining of the link text in the TRichEdit shrinks back so that the last word of the hyperlink text is no longer formatted in blue underline (no matter how long the hyperlink text is or how long the last word is) i.e I get this is a
and the space char in blue and underlined but not the word link
Can someone help me to append my ending token but still get all of the original hyperlink text shown formatted?
Code used to insert the hyperlink - before adding my ending token - this displays OK.
procedure TForm1.InsertHyperLink(const HyperlinkText, HyperlinkURL: string);
var
HyperlinkPrefix, FullHyperlink: string;
Fmt: CHARFORMAT2;
StartPos: Integer;
begin
if HyperlinkURL <> '' then
begin
HyperlinkPrefix := Format('HYPERLINK "%s"', [HyperlinkURL]);
FullHyperlink := HyperlinkPrefix + HyperlinkText;
end
else
begin
FullHyperlink := HyperlinkText;
end;
StartPos := RichEdit1.SelStart;
RichEdit1.SelText := FullHyperlink;
RichEdit1.SelStart := StartPos;
RichEdit1.SelLength := Length(FullHyperlink) ;
FillChar(Fmt, SizeOf(Fmt), 0);
Fmt.cbSize := SizeOf(Fmt);
Fmt.dwMask := CFM_LINK;
Fmt.dwEffects := CFE_LINK;
SendMessage(RichEdit1.Handle, EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(@Fmt));
if HyperlinkURL <> '' then
begin
RichEdit1.SelStart := StartPos ;
RichEdit1.SelLength := Length(HyperlinkPrefix);
FillChar(Fmt, SizeOf(Fmt), 0);
Fmt.cbSize := SizeOf(Fmt);
Fmt.dwMask := CFM_HIDDEN;
Fmt.dwEffects := CFE_HIDDEN;
SendMessage(RichEdit1.Handle, EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(@Fmt));
end;
RichEdit1.SelStart := StartPos + Length(FullHyperlink) ;
RichEdit1.SelLength := 0;
end;
Code used to insert the hyperlink but also append a closing token - this loses formatting of the last word in the link text.
procedure TForm1.InsertHyperLink(const HyperlinkText, HyperlinkURL: string);
const
TOKEN_LINK_END = ' ENDHYPERLINK';
var
HyperlinkPrefix, FullHyperlink: string;
Fmt: CHARFORMAT2;
StartPos: Integer;
begin
if HyperlinkURL <> '' then
begin
HyperlinkPrefix := Format('HYPERLINK "%s"', [HyperlinkURL]);
FullHyperlink := HyperlinkPrefix + HyperlinkText;
end
else
begin
FullHyperlink := HyperlinkText;
end;
StartPos := RichEdit1.SelStart;
RichEdit1.SelText := FullHyperlink;
RichEdit1.SelStart := StartPos;
RichEdit1.SelLength := Length(FullHyperlink) ;
FillChar(Fmt, SizeOf(Fmt), 0);
Fmt.cbSize := SizeOf(Fmt);
Fmt.dwMask := CFM_LINK;
Fmt.dwEffects := CFE_LINK;
SendMessage(RichEdit1.Handle, EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(@Fmt));
if HyperlinkURL <> '' then
begin
RichEdit1.SelStart := StartPos ;
RichEdit1.SelLength := Length(HyperlinkPrefix);
FillChar(Fmt, SizeOf(Fmt), 0);
Fmt.cbSize := SizeOf(Fmt);
Fmt.dwMask := CFM_HIDDEN;
Fmt.dwEffects := CFE_HIDDEN;
SendMessage(RichEdit1.Handle, EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(@Fmt));
end;
RichEdit1.SelStart := StartPos + Length(FullHyperlink) ;
RichEdit1.SelLength := 0;
///////////////////////////////////////////////////////////////////////////////
// //now add closing token as hidden text
///////////////////////////////////////////////////////////////////////////////
StartPos := RichEdit1.SelStart ;
RichEdit1.SelText := TOKEN_LINK_END;
RichEdit1.SelStart := StartPos;
RichEdit1.SelLength := Length(TOKEN_LINK_END);
FillChar(Fmt, SizeOf(Fmt), 0);
Fmt.cbSize := SizeOf(Fmt);
Fmt.dwMask := CFM_HIDDEN;
Fmt.dwEffects := CFE_HIDDEN;
SendMessage(RichEdit1.Handle, EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(@Fmt));
end;
Note This question is not about being able to click the links in the TRichEdit and get sent to the web site, so is not a duplicate of many others (Although I have written the code to do this by overriding WndProc, which works OK even though my last word is not shown formatted correctly)