我在对话框中添加了一个只读的富编辑2.0控件(代码使用的是C windows API,该对话框是使用函数DialogBox创建的)
在对话框回调中,在WM_INITDIALOG,我添加以下代码以启用URL检测,并启用事件ENM_LINK被发送到父对话框而不是富编辑控件本身:
LRESULT mask = SendMessage(hWndText, EM_GETEVENTMASK, 0, 0); //hWndText is rich edit control
SendMessage(hWndText, EM_SETEVENTMASK, 0, mask | ENM_LINK);
::SendMessage(hWndText, EM_AUTOURLDETECT, TRUE, NULL);
在最初启动对话框时启用url检测时遇到了一些麻烦(这似乎是一个已知的问题或行为,因为丰富的编辑控件只能启用对已修改文本的url检测)。但是,我通过在每个WM_PAINT事件上再次设置对话框文本来解决此问题。
代码通常有效。我还实现了以下代码,当鼠标悬停在url上时,在浏览器中启动URL:
case WM_NOTIFY:
plink = (ENLINK *) lParam;
switch(LOWORD(wParam))
{
case IDC_DISPLAY_TEXT_2: //this is ID for my rich edit control
szURL =m_strDisplay.Mid(plink->chrg.cpMin, plink->chrg.cpMax - plink->chrg.cpMin);
LaunchURL(szURL); //function to launch the url with default browser
break;
default:
break;
}
每当我将鼠标悬停在网址上时,我似乎都会收到WM_NOTIFY事件。但是,当我点击它时,我总是得到与鼠标悬停相同的事件。
基于ENLINK的结构,我应该在NMHDR结构中获得更详细的NM事件,但是plink-> nmhdr.code的值总是1803,甚至不是NM_HOVER(其定义的值是( NM_FIRST-13)和NM_FIRST是(0U-0U),因此我的64位机器上的NM_HOVER值是4294967283)。我知道我在这里遗漏了一些东西。有人会在这里点灯吗?如何获得富编辑控件的鼠标单击事件?
答案 0 :(得分:7)
我认为您应该抓取EN_LINK通知。我实现了以下代码。它允许将richedit控件中的url链接放入父窗口,而不是对话框。您也可以根据对话进行调整。
考虑从代码开始:
case WM_NOTIFY: {
switch (((LPNMHDR)lParam)->code) { //NMHDR structure contains information about a notification message.
case EN_LINK: {
ENLINK *enLinkInfo = (ENLINK *)lParam; // pointer to a ENLINK structure
然后,如果你选择在LBUTTONUP上启动url,你必须检查enLinkInfo->msg
中包含的值(记得根据你的对话调整它)
if (enLinkInfo->msg == WM_LBUTTONUP) {
// select all the text from enLinkInfo->chrg.cpMin to enLinkInfo->chrg.cpMax
// lauch the url
}
此外,你可以拦截WM_MOUSEMOVE:
if(enLinkInfo->msg == WM_MOUSEMOVE) {
; // do nothing
}
希望它有所帮助。
答案 1 :(得分:4)
正如@ A_nto2的回答所示,拦截鼠标点击:
case WM_NOTIFY: {
//NMHDR structure contains information about a notification message.
switch (((LPNMHDR)lParam)->code) {
case EN_LINK: {
ENLINK *enLinkInfo = (ENLINK *)lParam; // pointer to a ENLINK structure
if (enLinkInfo->msg == WM_LBUTTONUP) {
但棘手的部分是获取点击的链接。
一个得到一个"范围"已在enLinkInfo->chrg
类型的CHARRANGE
中点击。
对Detect click on URL in RichEdit的回答建议将EM_EXSETSEL
与enLinkInfo->chrg
一起使用。然后使用EM_GETSELTEXT
检索文本。
适用于自动检测到的纯文本网址(EM_AUTOURLDETECT
)。
问题在于友好名称超链接(即具有与URL本身不同的锚文本的超链接):
{\rtf1{\field{\*\fldinst{ HYPERLINK "https://www.example.com"}}{\fldrslt{Example}}}}
(请注意,Rich Edit 4.1及更新版本支持这些)
对于这些,CHARRANGE
指向HYPERLINK "https://www.example.com"
部分,该部分是隐藏的,无法使用EM_EXSETSEL
进行选择。实际上它可以在Windows 10上选择。但它无法在Windows 7,Vista和XP上选择。将EM_EXSETSEL
发送到这些系统会导致在隐藏部分之后选择零长度块。
因此,您必须返回丰富的编辑缓冲区并扫描链接;或使用其他方法检索点击的文字。
就我而言,因为我只在富编辑中有小文字,所以我使用了WM_GETTEXT
。它返回富文本编辑文档的纯文本版本,但是以这种形式保留了友好名称超链接:
HYPERLINK "https://www.example.com" Example
CHARRANGE
指向网址,奇怪的是包括引号:("https://www.example.com
)。
但索引对应于带有单字符(LF)行分隔符的文本。而WM_GETTEXT
返回CRLF分隔符。因此,在使用CHARRANGE
。
答案 2 :(得分:2)
根据EM_AUTOURLDETECT的文档,您应该收到EN_LINK通知,该通知应反映在nmhdr.code
中。根据谷歌的说法,
#define EN_LINK 0x70B
是7 * 256 + 11 = 1750 + 42 + 11 = 1803。
请注意,您的代码错过了对nmhdr.code == EN_LINK
。
我不确定控件是否会发送NM_HOVER
消息。