2010-03-19 7 views
5

Ich versuche RichEdit zu aktualisieren, so dass es URL erkennt und ermöglicht das Klicken auf es im Browser zu öffnen. Erkennen URL ist einfach, ich nutze einfach den folgenden Code aus http://www.scalabium.com/faq/dct0146.htmDetect Klick auf URL in RichEdit

mask := SendMessage(MNote.Handle, EM_GETEVENTMASK, 0, 0); 
    SendMessage(MNote.Handle, EM_SETEVENTMASK, 0, mask or ENM_LINK); 
    SendMessage(MNote.Handle, EM_AUTOURLDETECT, Integer(True), 0); 

aber der zweite Teil für mich nicht funktioniert. Sie geben den folgenden Code EN_LINK Nachricht zu erfassen und zu verarbeiten es:

type 
    TForm1 = class(TForm) 
    protected 
    procedure WndProc(var Message: TMessage); override; 
    end; 
... 

procedure TForm1.WndProc(var Message: TMessage); 
var 
    p: TENLink; 
    strURL: string; 
begin 
    if (Message.Msg = WM_NOTIFY) then 
    begin 
    if (PNMHDR(Message.LParam).code = EN_LINK) then 
    begin 
     p := TENLink(Pointer(TWMNotify(Message).NMHdr)^); 
     if (p.msg = WM_LBUTTONDOWN) then 
     begin 
     SendMessage(RichEdit1.Handle, EM_EXSETSEL, 0, LongInt(@(p.chrg))); 
     strURL := RichEdit1.SelText; 
     ShellExecute(Handle, 'open', PChar(strURL), 0, 0, SW_SHOWNORMAL); 
     end 
    end 
    end; 

    inherited; 
end; 

Wenn ich das Programm ausführen, URL erkannt wird, aber darauf klicken nicht alles tun. Beim Debugging habe ich festgestellt, dass Message.Msg = WM_NOTIFY nicht wahr ist, wenn ich auf URL klicke. Ich habe dann versucht, TRichEdit WndProc zu überschreiben, aber das Ergebnis ist das gleiche. Irgendwelche Vorschläge?

+0

Siehe auch [So implementieren Sie den Mausklick für URLs bei Rich-Edit-Steuerelement] (http://stackoverflow.com/q/11398248/850848). –

+0

Es funktioniert für mich. – Ampere

Antwort

7

Subclass der WindowProc Unterkunft RichEdit und für die Nachricht CN_NOTIFY suchen, zum Beispiel:

type 
    TForm1 = class(TForm) 
    RichEdit1: TRichEdit; 
    procedure FormCreate(Sender: TObject); 
    private 
    PrevRichEditWndProc: TWndMethod; 
    procedure RichEditWndProc(var Message: TMessage); 
    procedure SetRichEditMasks; 
    end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    PrevRichEditWndProc := RichEdit1.WindowProc; 
    RichEdit1.WindowProc := RichEditWndProc; 
    SetRichEditMasks; 
end; 

procedure TForm1.SetRichEditMasks; 
var 
    mask: Longint; 
begin 
    mask := SendMessage(RichEdit1.Handle, EM_GETEVENTMASK, 0, 0); 
    SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, mask or ENM_LINK); 
    SendMessage(RichEdit1.Handle, EM_AUTOURLDETECT, 1, 0); 
end; 

procedure TForm1.RichEditWndProc(var Message: TMessage); 
begin 
    PrevRichEditWndProc(Message); 
    case Message.Msg of 
    CN_NOTIFY: 
     begin 
     if (TWMNotify(Message).NMHdr^.code = EN_LINK) then 
     begin 
      with PENLink(Message.LParam)^ do 
      begin 
      if (msg = WM_LBUTTONDOWN) then 
      begin 
       SendMessage(RichEdit1.Handle, EM_EXSETSEL, 0, LongInt(@chrg)); 
       ShellExecute(Handle, 'open', PChar(RichEdit1.SelText), 0, 0, SW_SHOWNORMAL); 
      end; 
      end; 
     end; 
     end; 
    CM_RECREATEWND: 
     begin 
     SetRichEditMasks; 
     end; 
    end; 
end; 
0

Haben Sie es mit einer abgespeckten Anwendung versucht, um sicherzustellen, dass es nicht etwas anderes in Ihrem Programm ist, das Probleme verursacht? Ich habe die Schritte von dieser Website in Delphi 2009 ausgeführt und das Klicken auf URLs funktionierte einwandfrei.

1

Für mich ist es funktioniert nur, wenn der angezeigte Text der gleiche Text wie der zugrunde liegende Hyperlink ist.

Ich denke, mein Problem ist, dass der zugrunde liegende Hyperlink das Attribut CFE_HIDDEN hat und daher nicht von EM_EXSETSEL ausgewählt werden kann.

Als Beispiel, wenn ich (in WORD) eine Verknüpfung mit der URL http://www.rubbish.com erstellen, aber die den Text RUBBISH anzeigt, obwohl die CHRG des ausgewählten Textes 11-33 ist, die 22 Zeichen ist - die gleiche Länge wie die URL, der tatsächliche von der Methode zurückgegebene Text ist RUBBISH.

Allerdings habe ich festgestellt, dass, wenn ich WM_GETTEXT verwenden, die Gesamtheit der Verbindung zurückgegeben wird:

HYPERLINK „http://www.rubbish.com“ RUBBISH

aus dem ich extrahieren Die URL basiert auf dem Chrg.

Es fühlt sich ein wenig ungeschickt ... aber es funktioniert. :-)

+2

Da RichEdit die Verwendung der 'CFE_LINK'- und' CFE_HIDDEN'-Effekte für Friendly-Name-URLs mischt (siehe http://blogs.msdn.com/b/murrays/archive/2009/09/24/richedit-friendly-name-hyperlinks .aspx), vielleicht können Sie versuchen, 'EM_GETCHARFORMAT' zu verwenden, um die Zeichen um den angegebenen Charrange zu scannen, um zu erkennen, wo sich die versteckte URL tatsächlich befindet. –

+0

Für mich 'WM_GETTEXT' gibt Text mit CRLF-Zeilenenden zurück. Während der 'ENLink.chgr' scheint Indizes in Text mit einzelnen Zeichen (LF) Zeilenenden zu verwenden. Also musste ich den Text in LF konvertieren, bevor ich die URL mit 'ENLink.chgr' extrahieren konnte. Beachten Sie auch, dass die Methode "EM_EXSETSEL" an versteckten Texten unter Windows 10 (aber nicht unter Windows 7 und früher) funktioniert. Weitere Informationen finden Sie in meiner Antwort unter [So implementieren Sie den Mausklick für URLs unter Rich Edit Control] (http://stackoverflow.com/a/34825079/850848). –