我正在尝试更新RichEdit,以便它检测URL并允许单击它以在浏览器中打开.检测URL很简单,我只使用
http://www.scalabium.com/faq/dct0146.htm中的以下代码
mask := SendMessage(MNote.Handle,EM_GETEVENTMASK,0); SendMessage(MNote.Handle,EM_SETEVENTMASK,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,LongInt(@(p.chrg))); strURL := RichEdit1.SelText; ShellExecute(Handle,'open',PChar(strURL),SW_SHOWNORMAL); end end end; inherited; end;
当我运行程序时,检测到URL,但点击它不会做任何事情.使用调试我发现当我点击URL时,Message.Msg = WM_NOTIFY不成立.然后我试图覆盖TRichEdit的WndProc,但结果是一样的.有什么建议么?
解决方法
对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,0); SendMessage(RichEdit1.Handle,mask or ENM_LINK); SendMessage(RichEdit1.Handle,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,LongInt(@chrg)); ShellExecute(Handle,PChar(RichEdit1.SelText),SW_SHOWNORMAL); end; end; end; end; CM_RECREATEWND: begin SetRichEditMasks; end; end; end;