Richedit avec reconnaissance des urls

Contenu du snippet

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)

A voir également

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.