How to implement the mouse click for URLs at rich edit control

本秂侑毒 提交于 2019-12-05 13:35:42

I think you should capture the EN_LINK notification. I implemented the following code. It enables a url link in a richedit control placed into the parent window, not into a dialog. You could adapt it for your dialog, as well.

Consider beginning with the code:

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

then, if you choose to launch url on LBUTTONUP, you have to check the value contained in enLinkInfo->msg (remember to adapt it for your dialog, though)

 if (enLinkInfo->msg == WM_LBUTTONUP) {
// select all the text from enLinkInfo->chrg.cpMin to enLinkInfo->chrg.cpMax
// lauch the url

}

Besides, you can intercept WM_MOUSEMOVE:

if(enLinkInfo->msg == WM_MOUSEMOVE) {
                ; // do nothing
}

Hope it helps.

As the answer by @A_nto2 shows, to intercept a mouse click do:

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) {

But the tricky part is to get the link that was clicked on.

One gets a "range" that was clicked on in the enLinkInfo->chrg of the type CHARRANGE.

An answer to Detect click on URL in RichEdit suggests using the EM_EXSETSEL with the enLinkInfo->chrg. And then using the EM_GETSELTEXT to retrieve the text.

That works with auto-detected plain-text URLs (EM_AUTOURLDETECT).

A problem is with friendly name hyperlinks (i.e. those that have an anchor text different than the URL itself):

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

(Note that these are supported in Rich Edit 4.1 and newer only)

For these, the CHARRANGE points to the HYPERLINK "https://www.example.com" part, which is hidden and cannot be selected using the EM_EXSETSEL. Actually it can be selected on Windows 10. But it cannot be selected on Windows 7, Vista and XP. Sending the EM_EXSETSEL to these systems results in selecting a zero-length block just after the hidden part.

So either you have to go back in the rich edit buffer and scan for the link; or use another method to retrieve the clicked text.

In my case, as I have small texts only in the rich edit, I've used the WM_GETTEXT. It returns a plain-text version of the rich edit document, but with the friendly name hyperlinks preserved in this form:

HYPERLINK "https://www.example.com" Example

The CHARRANGE points to the URL, strangely including the leading quote: ("https://www.example.com).

But the indexes correspond to a text with a single-character (LF) line separators. While the WM_GETTEXT returns the CRLF separators. So you have to convert the text to the LF before extracting the URL using the CHARRANGE.

According to the documentation of EM_AUTOURLDETECT, you are supposed to get an EN_LINK notification, which should be reflected in the nmhdr.code. According to Google,

#define EN_LINK 0x70B

which is 7 * 256 + 11 = 1750 + 42 + 11 = 1803.

Please note that your code misses a check for nmhdr.code == EN_LINK.

I'm not sure if the control sends NM_HOVER messages at all.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!