如何在两个 RichEdit 控件中连续 select 内容?
How to continuously select content in TWO RichEdit controls?
我目前正在开发一个项目,其中两个 RichEdit 控件彼此靠近:假设 RichEdit1 在左侧,RichEdit2 在右侧。
我想在项目中启用的用户场景是:
- 用户鼠标 LButton 在 RichEdit1 的某处按下,例如在第3个字符之前,一共7个字符。
- 用户将鼠标拖到RichEdit2,例如第6个字符后,一共11个字符。
- 用户鼠标左键向上。
我想看到 RichEdit1 的第 3 个字符到结束和 RichEdit2 的开始到第 6 个字符都被选中。
目前我发现当我在RichEdit1上按下鼠标LButton后,当我将鼠标移动到RichEdit2后,RichEdit2在我松开鼠标之前收不到鼠标事件。
如有任何建议,我们将不胜感激。谢谢!
当鼠标在RichEdit1上被按下时,它会捕获鼠标,从而将后续的鼠标消息发送给RichEdit1,直到鼠标被释放。这就是为什么 RichEdit2 在 RichEdit2 上拖动时没有收到任何鼠标事件的原因。
您将不得不在 RichEdit1 中处理鼠标移动消息,并检查它们的坐标是否在 RichEdit1 的客户区之外。如果是,将它们转换成相对于RichEdit2客户区的坐标,然后根据需要发送EM_SETSEL
/EM_EXSETSEL
消息给RichEdit2。例如:
int RichEdit2StartIndex = -1;
...
// in RichEdit1's message handler...
case WM_MOUSEMOVE:
{
if ((wParam & MK_LBUTTON) == 0)
break;
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
RECT r;
GetClientRect(hwndRichEdit1, &r);
if (xPos < (r.right - r.left))
{
if (RichEdit2StartIndex != -1)
{
SendMessage(hwndRichEdit2, EM_SETSEL, -1, 0);
RichEdit2StartIndex = -1;
}
}
else
{
POINT pt;
pt.x = xPos;
pt.y = yPos;
MapWindowPoints(hwndRichEdit1, hwndRichEdit2, &pt, 1);
POINTL pl;
Pl.x := pt.x;
Pl.y := pt.y;
int idx = SendMessage(hwndRichEdit2, EM_CHARFROMPOS, 0, (LPARAM)&Pl);
if (idx != -1)
{
if (RichEdit2StartIndex == -1)
RichEdit2StartIndex = idx;
SendMessage(hwndRichEdit2, EM_SETSEL, RichEdit2StartIndex, idx);
}
}
break;
}
将选区从 RichEdit2 拖动到 RichEdit1 时反之亦然。
并确保两个 RichEdit 控件都应用了 ES_NOHIDESEL
样式,以便您可以同时在两个控件中看到选择。
我目前正在开发一个项目,其中两个 RichEdit 控件彼此靠近:假设 RichEdit1 在左侧,RichEdit2 在右侧。
我想在项目中启用的用户场景是:
- 用户鼠标 LButton 在 RichEdit1 的某处按下,例如在第3个字符之前,一共7个字符。
- 用户将鼠标拖到RichEdit2,例如第6个字符后,一共11个字符。
- 用户鼠标左键向上。
我想看到 RichEdit1 的第 3 个字符到结束和 RichEdit2 的开始到第 6 个字符都被选中。
目前我发现当我在RichEdit1上按下鼠标LButton后,当我将鼠标移动到RichEdit2后,RichEdit2在我松开鼠标之前收不到鼠标事件。
如有任何建议,我们将不胜感激。谢谢!
当鼠标在RichEdit1上被按下时,它会捕获鼠标,从而将后续的鼠标消息发送给RichEdit1,直到鼠标被释放。这就是为什么 RichEdit2 在 RichEdit2 上拖动时没有收到任何鼠标事件的原因。
您将不得不在 RichEdit1 中处理鼠标移动消息,并检查它们的坐标是否在 RichEdit1 的客户区之外。如果是,将它们转换成相对于RichEdit2客户区的坐标,然后根据需要发送EM_SETSEL
/EM_EXSETSEL
消息给RichEdit2。例如:
int RichEdit2StartIndex = -1;
...
// in RichEdit1's message handler...
case WM_MOUSEMOVE:
{
if ((wParam & MK_LBUTTON) == 0)
break;
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
RECT r;
GetClientRect(hwndRichEdit1, &r);
if (xPos < (r.right - r.left))
{
if (RichEdit2StartIndex != -1)
{
SendMessage(hwndRichEdit2, EM_SETSEL, -1, 0);
RichEdit2StartIndex = -1;
}
}
else
{
POINT pt;
pt.x = xPos;
pt.y = yPos;
MapWindowPoints(hwndRichEdit1, hwndRichEdit2, &pt, 1);
POINTL pl;
Pl.x := pt.x;
Pl.y := pt.y;
int idx = SendMessage(hwndRichEdit2, EM_CHARFROMPOS, 0, (LPARAM)&Pl);
if (idx != -1)
{
if (RichEdit2StartIndex == -1)
RichEdit2StartIndex = idx;
SendMessage(hwndRichEdit2, EM_SETSEL, RichEdit2StartIndex, idx);
}
}
break;
}
将选区从 RichEdit2 拖动到 RichEdit1 时反之亦然。
并确保两个 RichEdit 控件都应用了 ES_NOHIDESEL
样式,以便您可以同时在两个控件中看到选择。