0

I'm currently working on project which will have two RichEdit controls one close to the other: let's say RichEdit1 is on left and RichEdit2 is on the right.

The user scenario I want to enable in the project is:

  1. User mouse LButton down at somewhere in RichEdit1, e.g. before the 3rd char, in total 7 chars.
  2. User drag the mouse to RichEdit2, e.g. after the 6th char, in total 11 chars.
  3. User mouse LButton up.

I want to see both RichEdit1 3rd char to end and RichEdit2 begin to 6th char are selected.

Currently I notice that once mouse LButton down on RichEdit1, after I move the mouse to RichEdit2, the RichEdit2 could not receive mouse event before I release mouse.

Any suggestion will be appreciated. Thank you!

NonStatic
  • 951
  • 1
  • 8
  • 27

1 Answers1

1

When the mouse button is pressed down on RichEdit1, it captures the mouse, thus subsequent mouse messages are sent to RichEdit1 until the mouse button is released. That is why RichEdit2 does not receive any mouse events while dragging over RichEdit2.

You will have to process the mouse move messages in RichEdit1 and check if their coordinates are outside of RichEdit1's client area. If so, convert them into coordinates relative to RichEdit2's client's area and then send EM_SETSEL/EM_EXSETSEL messages to RichEdit2 as needed. For example:

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;
}

Vice versa when dragging a selection from RichEdit2 to RichEdit1.

And make sure that both RichEdit controls have the ES_NOHIDESEL style applied so you can see the selection in both controls at the same time.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I was trying to find a property in RichEdit to solve the problem but seems this way is also not bad. Thank you Remy! – NonStatic Jul 28 '15 at 18:52