6

I'm trying to implement URL detection for TRichEdit component using EM_AUTOURLDETECT message.
I have a problem with the following code

procedure TForm1.Button1Click(Sender: TObject);
var Mask: Word;
begin
  Mask := SendMessage(Handle, EM_GETEVENTMASK, 0, 0);
  SendMessage(Handle, EM_SETEVENTMASK, 0, Mask or ENM_LINK);
  SendMessage(Handle, EM_AUTOURLDETECT, Integer(True), 0);
end;

It works though but I have to change the TRichEdit's text after these settings to get the it detect the URLs in already written text. And that's the problem because my TRichEdit is in ReadOnly mode when applying this feature.

What should I do after performing this code to force the TRichEdit to detect URLs in already written text ?
I was looking at the documentation but there's no mention about something like this.

Thank you

Martin Reiner
  • 2,167
  • 2
  • 20
  • 34

1 Answers1

5

I've had the same problem some time ago and used (quite) a dirty workaround for it. After sending of the EM_AUTOURLDETECT message I get and store the current selection, then (re)set the rich edit's text and set back the selection stored before.

procedure TForm1.Button1Click(Sender: TObject);
var
  EventMask: Word;
  CharRange: TCharRange;
begin
  EventMask := SendMessage(RichEdit1.Handle, EM_GETEVENTMASK, 0, 0);
  SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, EventMask or ENM_LINK);
  SendMessage(RichEdit1.Handle, EM_AUTOURLDETECT, WPARAM(True), 0);
  SendMessage(RichEdit1.Handle, EM_EXGETSEL, 0, LPARAM(@CharRange));
  SendMessage(RichEdit1.Handle, WM_SETTEXT, 0, LPARAM(RichEdit1.Text));
  SendMessage(RichEdit1.Handle, EM_EXSETSEL, 0, LPARAM(@CharRange));
end;
TLama
  • 75,147
  • 17
  • 214
  • 392
  • 1
    Thanks TLama but isn't there more clean technique to do it ? Some kind of single notification ? It looks quite "heavy" to clear and set the TRichEdit's text back. – Martin Reiner Jan 17 '12 at 16:21
  • 3
    In documentation there's the following: _If automatic URL detection is enabled, the rich edit control scans any modified text to determine whether the text matches the format of a URL._ so it seems the text should be modified to get this format, but if there's an easier way (some notification as you say) to force the system to apply `CFE_LINK` effect for all words already present in rich edit I don't know. – TLama Jan 17 '12 at 16:31
  • 2
    no other workaround AFIK. a simplified code would be: `SendMessage(RichEdit1.Handle, WM_SETTEXT, 0, Longint(RichEdit1.Text));` after you set `EM_AUTOURLDETECT` – kobik Jan 17 '12 at 17:08
  • 1
    @kobik, you're right, thanks. And it will look much more stylish. I'll include it into the answer with excuse ;) – TLama Jan 17 '12 at 18:34
  • 1
    I think VCL way to do that is RecreateWnd call – OnTheFly Jan 17 '12 at 18:48
  • @user539484, it's impossible because `TRichedit` has no `RecreateWnd` published and even if you would like e.g. perform the `CM_RECREATEWND` message explicitly, nothing happens (what is fair enough because it's only for underlying controls :) – TLama Jan 18 '12 at 09:43
  • @TLama, this method is never supposed to be `published`. `RecreateWnd`'s purpose is to cope with control styles which cannot be set on live control: *Some changes in control properties are not implemented until this re-creation occurs.* – OnTheFly Jan 18 '12 at 14:07
  • @user539484, it is published e.g. for form; but anyway `RecreateWnd` applies changes for some properties though but not for effects which are set explicitly. The `TRichedit` doesn't store this setting anywhere and if so, you would have to call the `EM_AUTOURLDETECT` at some creation method or property setter (and if property setter, then you would have to set that property in the creation method) to get it applied. – TLama Jan 18 '12 at 14:44
  • @TLama, *it is published e.g. for form* – No, it and always been **protected**. *TRichedit doesn't store this setting anywhere* – TCustomRichEdit have predefined event mask, if you want to set more flags - send the message in eg: `CreateWnd`. – OnTheFly Jan 19 '12 at 02:31
  • @user539484, well, `RecreateWnd` is always protected, but you can call it from unit namespace for `TForm` so it is _published_ in the meaning of the word (not technically). But still, even `RecreateWnd` doesn't affect setting of the `EM_AUTOURLDETECT` without changing text (see my temporary edit). – TLama Jan 19 '12 at 08:50