如何禁用RichEdit控件文本选择光标并保留超链接手型光标
我想在RichEdit控件中显示标准"pointer"箭头光标,替代默认的"文本选择光标"(如下图所示):
目前我能想到的唯一方案是在窗口中拦截WM_SETCURSOR消息,判断光标处于RichEdit控件范围内时将其替换为普通箭头光标。但该方案不够简便,同时我需要保留光标指向超链接时显示的手型光标。
请问是否有更简单的实现方法?
更新:针对评论的补充说明:
- @Remy Lebeau:我实际需要的是具备以下能力的文本展示控件:自动换行、同段文本内不同字符可设置不同颜色、支持超链接、可按需展示图片,且需要支持加载网络文本、在单个控件内展示,同时可以通过写字板这类RTF编辑器快速生成对应内容。但RichEdit内展示的信息不允许编辑或复制,去掉文本选择光标更符合应用设计需求,所以我认为RichEdit是合适的选择,当然也欢迎推荐其他替代方案。
- @Jeaninez:我已经设置了
ES_READONLY属性,但它既不会改变光标样式,也不会禁止文本选中,后者我已经通过拦截EN_SELCHANGE通知解决了。 - @Barmak Shemirani:我可以处理超链接事件,目前我使用的光标切换代码片段如下:
// 该方法处理WM_SETCURSOR消息 LRESULT MainWindow::OnSetCursor(WPARAM wParam, LPARAM lParam) { auto h = (HWND)wParam; if (h == richEditHwnd) { return TRUE; // 阻止后续处理器修改光标 } return DefWindowProc(mainWindowHandle, WM_SETCURSOR, wParam, lParam); }
更新2:根据Barmak Shemirani在评论中的提示,ENLINK通知可由鼠标事件触发,目前我已经有了接近可用的方案(不过我还没完全搞懂其运行逻辑):
WM_SETCURSOR处理函数:
LRESULT MainWindow::OnSetCursor(WPARAM wParam, LPARAM lParam) { auto h = (HWND)(wParam); if (rich.hwnd == h) { if (HIWORD(lParam) == WM_MOUSEMOVE || HIWORD(lParam) == WM_LBUTTONDOWN || HIWORD(lParam)== WM_LBUTTONDBLCLK) { DefWindowProc(windowHandle, WM_SETCURSOR, wParam, lParam); auto cursor = LoadCursor(NULL, IDC_ARROW); SetClassLongPtr(rich.hwnd, GCLP_HCURSOR, (LONG_PTR)cursor); return true; } } return DefWindowProc(windowHandle, WM_SETCURSOR, wParam, lParam); }
EM_LINK通知处理函数:
auto enLink = (ENLINK*)lParam; if (enLink->msg == WM_LBUTTONUP) { std::wstring linkId(enLink->chrg.cpMax - enLink->chrg.cpMin, L'0'); TEXTRANGE textRange{enLink->chrg, (LPTSTR)linkId.data()}; SendMessage(nmHeader->hwndFrom, EM_GETTEXTRANGE, NULL, reinterpret_cast<LPARAM>(&textRange)); ProcessLinkClick(enLink, linkId); } else if (enLink->msg == WM_MOUSEMOVE || enLink->msg == WM_LBUTTONDBLCLK || enLink->msg == WM_LBUTTONDOWN) { auto cursor = LoadCursor(NULL, IDC_HAND); SetClassLongPtr(enLink->nmhdr.hwndFrom, GCLP_HCURSOR, (LONG_PTR)cursor); return TRUE; } return 0;
这段代码在lParam为WM_MOUSEMOVE和WM_LBUTTONDOWN时运行正常,但处理WM_LBUTTONDBLCLK时会失效。
更新3:
我之前推出的代码过于仓促,它会阻塞EM_LINK通知的WM_LBUTTONUP消息,导致我无法正常处理超链接点击事件。
内容的提问来源于stack exchange,提问作者qloq
相关产品推荐
相关产品推荐

