IRichEdit控件中鼠标悬停图片调整手柄时更改光标
无窗口Rich Edit控件图片调整手柄光标处理方案
一、Rich Edit默认行为说明
无窗口Rich Edit控件不会自动处理调整手柄悬停时的光标切换,所有光标逻辑需要手动实现。
二、获取选中图片的位置与尺寸
要获取选中图片的区域,需通过EM_GETOBJECT消息配合REOBJECT结构体操作:
- 先验证选中对象类型:发送
EM_SELECTIONTYPE消息,若返回值为SEL_EMBEDDED或SEL_LINK,则当前选中的是嵌入图片。 - 发送
EM_GETOBJECT获取图片的矩形信息:REOBJECT reObj = {0}; reObj.cbStruct = sizeof(REOBJECT); if (SendMessage(hRichEdit, EM_GETOBJECT, 0, (LPARAM)&reObj)) { // reObj.rc 为图片在无窗口控件客户区的矩形 RECT imgRect = reObj.rc; } - 坐标转换:无窗口控件的坐标基于宿主窗口,需用
MapWindowPoints将全局光标坐标转换为控件内部坐标。
三、判断鼠标是否悬停在调整手柄上
八个调整手柄对应图片矩形的角落与边中点,每个手柄可定义为8x8像素的小矩形。在WM_MOUSEMOVE消息中,通过以下步骤判断:
- 获取并转换鼠标坐标到控件内部坐标系。
- 逐个检查鼠标是否落在某个手柄区域,匹配对应光标:
POINT cursorPt; GetCursorPos(&cursorPt); // 转换到宿主窗口坐标 MapWindowPoints(NULL, hHostWnd, &cursorPt, 1); // 转换到无窗口控件内部坐标(假设控件在宿主窗口的位置为ctrlRect) cursorPt.x -= ctrlRect.left; cursorPt.y -= ctrlRect.top; // 左上角手柄(对应NW-SE方向光标) RECT nwHandle = {imgRect.left - 4, imgRect.top - 4, imgRect.left + 4, imgRect.top + 4}; if (PtInRect(&nwHandle, cursorPt)) { SetCursor(LoadCursor(NULL, IDC_SIZENWSE)); return TRUE; } // 右上角手柄(NE-SW方向) RECT neHandle = {imgRect.right - 4, imgRect.top - 4, imgRect.right + 4, imgRect.top + 4}; if (PtInRect(&neHandle, cursorPt)) { SetCursor(LoadCursor(NULL, IDC_SIZENESW)); return TRUE; } // 上边中点(垂直缩放光标) RECT topMidHandle = {imgRect.left + (imgRect.right - imgRect.left)/2 -4, imgRect.top -4, imgRect.left + (imgRect.right - imgRect.left)/2 +4, imgRect.top +4}; if (PtInRect(&topMidHandle, cursorPt)) { SetCursor(LoadCursor(NULL, IDC_SIZENS)); return TRUE; } // 其余手柄同理,对应不同系统光标ID
四、完整实现要点
- 在宿主窗口的
WM_MOUSEMOVE和WM_SETCURSOR消息中处理光标逻辑,确保光标实时更新。 - 当未选中图片或鼠标不在手柄区域时,恢复控件默认光标。
内容的提问来源于stack exchange,提问作者NiceTry
相关产品推荐
相关产品推荐

