在Rich Edit Control 中显示超链接的格式,也就是给选择的文本添加CFE_LINK属性,可以通过以下两种方法实现:
http: file: mailto: ftp: https: gopher: nntp: prospero: telnet: news: wais:
(1)打开自动检测
CWnd *pRE = GetDlgItem(IDC_RICHEDIT1); pRE->SendMessage(EM_AUTOURLDETECT, TRUE, 0);
(2)关闭自动检测
CWnd *pRE = GetDlgItem(IDC_RICHEDIT1); pRE->SendMessage(EM_AUTOURLDETECT, FALSE, 0);
(3)判断当前自动检测是否打开
BOOL bEnable = pRE->SendMessage(EM_GETAUTOURLDETECT, 0, 0);
CWnd *pRE = GetDlgItem(IDC_RICHEDIT1); CHARFORMAT2 cf; ZeroMemory(&cf, sizeof(CHARFORMAT2)); cf.cbSize = sizeof(CHARFORMAT2); cf.dwMask = CFM_LINK; cf.dwEffects |= CFE_LINK; pRE->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
(2)去除CFE_LINK
CWnd *pRE = GetDlgItem(IDC_RICHEDIT1); CHARFORMAT2 cf; ZeroMemory(&cf, sizeof(CHARFORMAT2)); cf.cbSize = sizeof(CHARFORMAT2); cf.dwMask = CFM_LINK; cf.dwEffects &= ~CFE_LINK; pRE->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
使用以上方法我们已经可以通过自动或手动显示一个超链接,接着我们需要做的是处理超链接的事件(WM_SETCURSOR、WM_MOUSEMOVE、WM_RBUTTONDOWN、WM_RBUTTONUP、WM_RBUTTONDBCLK、WM_LBUTTONDOWN、WM_LBUTTONUP、WM_LBUTTONDBCLK),所有这些都通过由Rich Edit Control 发送的EN_LINK消息通知父窗口,父窗口可以在WM_NOTIFY中接收到EN_LINK消息。具体实现如下:
1、通知Rich Edit Control 发送EN_LINK消息,默认情况下是不发送的,在初始化控件时添加:
CWnd *pRE = GetDlgItem(IDC_RICHEDIT1); DWORD dwMask = pRE-> SendMessage(EM_GETEVENTMASK, 0L, 0L); dwMask |= ENM_LINK; pRE-> SendMessage(EM_SETEVENTMASK, 0L, (LPARAM)dwMask);
2、在WM_NOTIFY消息中处理EN_LINK。
NMHDR *p = (NMHDR *)lParam; if (p->code == EN_LINK) { ENLINK *pLink = (ENLINK *)lParam; switch(pLink->msg) { case WM_LBUTTONDOWN: //鼠标左键按下 break; case WM_LBUTTONUP: {//鼠标左键松开 char strBuf[512]; CWnd *pRE = GetDlgItem(IDC_RICHEDIT1); pRE->SendMessage(EM_EXSETSEL, 0, (LPARAM)&(pLink->chrg)); pRE->SendMessage(EM_GETSELTEXT, 0, (LPARAM)strBuf); ::ShellExecute(NULL, _T("open"), _T("iexplore"), strBuf, NULL, SW_SHOWNORMAL); break; } default: break; } }
通过前边介绍的方法,我们可以得到两种超链接,一种是打开URL自动检测时控件自动显示的,通常只需要用iexplore打开即可,例如打开一个网页、发送一封邮件、打开一个窗口等等;另一种是手动添加的,我们可能会需要对每个超链接执行不同的操作,问题是如何区分不同的超链接呢?这是我们接下来要讨论的问题。
区分超链接首先想到的是可以根据文本来区分,不同文本对应不同操作,这就需要在超链接HyperLinkText和操作Action之间建立一个映射,我们可以在添加超链接HyperLinkText时用CMap来保存<HyperLinkText, Action>,利用这个map就可以很方便知道那个超链接进行那个操作。另外对于系统自动识别的URL,我们并没有保存映射,就可以通过iexplore进行默认操作:
Action = map[HyperLinkText]; if (Action == Action1) { //Action1 } else if (Action == Action2) { //Action2 } else { //其他URL,使用iexplore打开 }
对于一些简单的操作这种方法确实可以满足要求了,但是如果出现多个相同文本的超链接,而且这些超链接对应的操作又不同,该如何区分呢?很显然仅通过文本已经无法唯一确定了,必须经过其他的特征帮助区分,在这里我使用了超链接文本的开始位置,就是CHARRANGE中的cpMin,这个位置在文本中是唯一的,在添加超文本时把<cpMin, Action>做一个映射保存在CMap中,这样当我们点击一个超链接时可以通过每个文本的开始位置cpMin找到Action,从而进行相应的操作:
Action = map[cpMin]; if (Action == Action1) { //Action1 } else if (Action == Action2) { //Action2 } else { //其他URL,使用iexplore打开 }
现在我们已经可以准确控制每个超链接的操作了。如果你需要保存更多信息,可以把<cpMin, Action>中的Action用一个结构来代替<cpMin, HyperLink>,例如:
typedef struct _HyperLink { WORD Action; DWORD dwId; } HyperLink;