-->

如何实现在丰富的编辑控件的URL鼠标点击(How to implement the mouse cl

2019-09-19 06:37发布

我添加了丰富的只读编辑2.0控制,以我的对话框(代码是用C窗户API,通过使用功能创建对话框对话框 )

在对话框回调,在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检测到已知的问题或行为)。 但是我的工作解决此问题通过在每个WM_PAINT事件再次设置对话框文本。

该代码是一般的工作。 我还实施下面的代码在浏览器中启动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事件,当我徘徊在鼠标的URL。 然而,当我点击它,我总是得到相同的事件作为鼠标悬停。

基于所述结构ENLINK ,我应该在NMHDR结构获得更详细的NM事件,然而值plink-> nmhdr.code总是1803这是不连NM_HOVER(其定义的值是(NM_FIRST-13)和NM_FIRST被( 0U- 0U),所以NM_HOVER值是4294967283我的64位计算机上)。 我知道,我在这里失去了一些东西。 可能有人阐明一些灯吗? 我怎样才能获得丰富的编辑控制鼠标点击事件?

Answer 1:

我想你应该捕捉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
}

希望能帮助到你。



Answer 2:

正如@ 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

回答检测点击RichEdit中URL使用建议EM_EXSETSELenLinkInfo->chrg 。 然后使用EM_GETSELTEXT检索的文本。

这可与自动检测到纯文本的URL( EM_AUTOURLDETECT )。

一个问题是与友好的名称链接(即那些具有比URL本身不同的锚文本):

{\rtf1{\field{\*\fldinst{ HYPERLINK "https://www.example.com"}}{\fldrslt{Example}}}}

(请注意,这些都是在丰富的编辑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指向URL,奇怪包括领先的报价:( "https://www.example.com )。

但指数对应于具有单字符(LF)行分隔符文本。 虽然WM_GETTEXT返回CRLF分隔符。 所以,你必须使用提取的网址前文的LF转换CHARRANGE



Answer 3:

据文件EM_AUTOURLDETECT ,你应该得到一个EN_LINK通知,应该在体现nmhdr.code 。 据谷歌,

#define EN_LINK 0x70B

这是7 * 256 + 11 = 1750 + 42 + 11 = 1803。

请注意,您的代码错过了支票nmhdr.code == EN_LINK

我不知道如果控制发送NM_HOVER消息都没有。



文章来源: How to implement the mouse click for URLs at rich edit control