我正在尝试更新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;