检测 RichEdit 中 URL 的点击
我正在尝试更新 RichEdit,以便它检测 URL 并允许单击它在浏览器中打开。检测 URL 很容易,我只需使用 http://www.scalabium.com/faq 中的以下代码/dct0146.htm
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,但单击它不会执行任何操作。使用调试我发现当我单击 URL 时 Message.Msg = WM_NOTIFY 不正确。然后我尝试覆盖 TRichEdit 的 WndProc,但结果是相同的。有什么建议吗?
I am trying to update RichEdit so that it detects URL and enables clicking on it to open in the browser. Detecting URL is easy, I just use the following code from http://www.scalabium.com/faq/dct0146.htm
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);
but the second part doesn't work for me. They give the following code to capture EN_LINK message and processing it:
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;
When I run the program, URL is detected, but clicking on it doesn't do anything. Using debug I found out that Message.Msg = WM_NOTIFY is not true when I click on URL. I then tried to override TRichEdit's WndProc, but result is the same. Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对 RichEdit 的 WindowProc 属性进行子类化并查找 CN_NOTIFY 消息,例如:
Subclass the RichEdit's WindowProc property and look for the CN_NOTIFY message, for example:
对我来说,只有显示的文本与底层超链接的文本相同时它才有效。
我认为我的问题是底层超链接具有属性 CFE_HIDDEN,因此无法由 EM_EXSETSEL 选择。
例如,如果我(在 WORD 中)创建一个网址为 http://www.rubbish.com 的链接,但它显示文本 RUBBISH,虽然所选文本的 chrg 是 11-33,即 22 个字符 - 与 URL 长度相同,但该方法返回的实际文本是 RUBBISH。
但是,我发现如果我使用 WM_GETTEXT,则会返回整个链接:
HYPERLINK "http://www.rubbish.com" RUBBISH
我可以从中提取基于 chrg 的 URL。
感觉有点笨拙……但确实有效。 :-)
For me, it only works if the displayed text is the same text as the underlying hyperlink.
I think my problem is that the underlying hyperlink has the attribute CFE_HIDDEN, and so can't be selected by EM_EXSETSEL.
As an example, if I create (in WORD) a link with the url http://www.rubbish.com, but which displays the text RUBBISH, although the chrg of the selected text is 11-33 which is 22 characters - the same length as the URL, the actual text returned by the method is RUBBISH.
However, I've discovered that if I use WM_GETTEXT, the whole of the link is returned:
HYPERLINK "http://www.rubbish.com" RUBBISH
From which I can extract the URL based on the chrg.
It feels a little clumsy... but it works. :-)
您是否尝试过使用精简的应用程序来确保程序中的其他内容不会导致问题?我按照 Delphi 2009 中该网站的步骤操作,单击 URL 效果很好。
Have you tried it with a stripped down application to make sure it isn't something else in your program causing problems? I followed the steps from that website in Delphi 2009 and clicking URLs worked just fine.