c'est une simple extension du richedit fourni en standard avec la VCL, qui détecte automatiquement les urls et déclenche un évènement en cas de clic sur celles-ci.
une procédure est également disponible pour donner l'attribut "lien" à la sélection courante (par exemple pour mettre comme liens des adresses emails sans avoir besoin du mailto: devant).
j'ai également rajouté deux évènements: OnMouseEnter et OnMouseLeave ;-)
Source / Exemple :
unit RichEditEx;
interface
uses
Forms, Windows, Messages, SysUtils, Classes, Controls, Graphics, ComCtrls, RichEdit;
type
PENLink = ^TENLink;
TLinkClickEvent = procedure(Sender: TObject; LinkClicked: String) of Object;
TRichEditEx = class(TRichEdit)
private
FOnLinkClicked: TLinkClickEvent;
FOnMouseEnter: TNotifyEvent;
FOnMouseLeave: TNotifyEvent;
protected
procedure CreateWnd; override;
procedure CNNotify(var Msg: TWMNotify); message CN_NOTIFY;
procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetSelectionLink;
published
property OnLinkClicked: TLinkClickEvent read FOnLinkClicked write FOnLinkClicked;
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
end;
procedure Register;
implementation
constructor TRichEditEx.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FOnLinkClicked := nil;
FOnMouseEnter := nil;
FOnMouseLeave := nil;
end;
destructor TRichEditEx.Destroy;
begin
inherited Destroy;
end;
procedure TRichEditEx.CreateWnd;
begin
inherited CreateWnd;
SendMessage(Handle, EM_SETEVENTMASK, 0, SendMessage(Handle, EM_GETEVENTMASK, 0, 0) or ENM_LINK);
SendMessage(Handle, EM_AUTOURLDETECT, 1, 0);
end;
procedure TRichEditEx.CNNotify(var Msg: TWMNotify);
var
TR: TTextRangeA;
begin
if Msg.NMHdr.code = EN_LINK
then begin
if Assigned(OnLinkClicked)
then begin
if PENLink(Msg.NMHdr).msg = WM_LBUTTONUP
then begin
TR.chrg := PENLink(Msg.NMHdr).chrg;
GetMem(TR.lpStrText, TR.chrg.cpMax - TR.chrg.cpMin + 2);
SendMessage(Handle, EM_GETTEXTRANGE, 0, Integer(addr(TR)));
OnLinkClicked(Self, TR.lpStrText);
FreeMem(TR.lpStrText);
end;
end;
Msg.Result := 0;
end else begin
inherited;
end;
end;
procedure TRichEditEx.CMMouseEnter(var Msg: TMessage);
begin
if Enabled
then begin
if Assigned(OnMouseEnter) then OnMouseEnter(Self);
end;
end;
procedure TRichEditEx.CMMouseLeave(var Msg: TMessage);
begin
if Enabled
then begin
if Assigned(OnMouseLeave) then OnMouseLeave(Self);
end;
end;
procedure TRichEditEx.SetSelectionLink;
var
CF: TCharFormatA;
begin
FillChar(CF, SizeOf(CF), 0);
CF.cbSize := SizeOf(CF);
CF.dwMask := CFM_LINK;
CF.dwEffects := CFE_LINK;
SendMessage(Handle, EM_SETCHARFORMAT, SCF_SELECTION, Integer(addr(CF)));
end;
procedure Register;
begin
RegisterComponents('Win32', [TRichEditEx]);
end;
end.
Conclusion :
composant basé sur le code suivant :
http://www.codeguru.com/richedit/RichEdit20.shtml
limitations : la détection automatique des urls (et leur clic, le cas échéant) ne fonctionne que sur windows 2000 / XP en raison des différences de versions des DLL riched32.dll et riched20.dll, si vous savez comment redéfinir l'objet richedit en utilisant riched20.dll plutot que riched32.dll, merci de me l'indiquer ;-)
je cherche également comment insérer des objets bitmaps dans un richedit, si vous le savez, laissez moi un commentaire svp (j'ai bien trouvé des méthodes sur le même site que ci-dessus, mais ça m'a donné mal à la tête, moi et le c++ on est pas copains lol)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.