2010-03-19 53 views
5

我在嘗試更新RichEdit,以便它檢測到URL並使其能夠在瀏覽器中單擊打開。檢測URL是容易的,我只是用下面的代碼從http://www.scalabium.com/faq/dct0146.htm在RichEdit中檢測URL的點擊

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); 

但第二部分沒有爲我工作。他們給下面的代碼來捕獲EN_LINK消息並處理它:

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; 

當我運行程序,當檢測到的網址,但點擊它沒有做任何事情。使用調試我發現,當我點擊URL時,Message.Msg = WM_NOTIFY是不正確的。然後我試圖覆蓋TRichEdit的WndProc,但結果是一樣的。有什麼建議麼?

+0

另請參閱[如何在富編輯控件中實現鼠標點擊URL](http://stackoverflow.com/q/11398248/850848)。 – 2016-01-16 08:43:43

+0

它適用於我。 – Ampere 2017-03-01 12:42:12

回答

7

子類在RichEdit的WindowProc屬性,並查找CN_NOTIFY消息,例如:

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

你有沒有試過它與一個剝離下來的應用程序,以確保它不是在你的程序中導致問題的其他東西?我遵循了Delphi 2009中該網站的步驟,並點擊了很好的網址。

1

對我來說,只有當顯示的文本是相同的文字作爲基礎的超鏈接工作。

我想我的問題是底層的超鏈接有屬性CFE_HIDDEN,所以不能被EM_EXSETSEL選中。例如,如果我使用url創建(在WORD中)鏈接,但顯示的是文本垃圾信息,儘管所選文本的chrg是11-33,它是22個字符 - 長度與URL,該方法返回的實際文本是垃圾郵件。

然而,我發現,如果我使用WM_GETTEXT,則返回整個環節:

HYPERLINK「http://www.rubbish.com」垃圾

從中我可以提取基於chrg的URL。

這感覺有點笨拙......但它的工作原理。 :-)

+2

由於RichEdit將「CFE_LINK」和「CFE_HIDDEN」效果用於友好名稱URL(請參閱http://blogs.msdn.com/b/murrays/archive/2009/09/24/richedit-friendly-name-hyperlinks .aspx),也許你可以嘗試使用'EM_GETCHARFORMAT'掃描指定字符的字符來檢測隱藏的URL的實際位置。 – 2011-03-31 06:34:20

+0

對我來說,'WM_GETTEXT'返回帶有CRLF行結尾的文本。雖然'ENLink.chgr'似乎在帶有單字符(LF)行結尾的文本中使用索引。所以我必須在使用'ENLink.chgr'提取URL之前將文本轉換爲LF。另請注意,'EM_EXSETSEL'方法可用於Windows 10上的隱藏文本(但不適用於Windows 7及更早版本)。有關詳細信息,請參閱我在[如何在豐富的編輯控件上實現鼠標點擊URL]的答案(http://stackoverflow.com/a/34825079/850848)。 – 2016-01-16 08:41:30