RichTextBox does not trigger selection on the mouse when the form is not focused

I use WinForms, and in my form I have a RichTextBox. When my form is out of focus, but visible, and I try to select / select text, this does not allow me until the form itself or the text field are concentrated.

I tried:

txtInput.MouseDown += (s, e) => { txtInput.Focus(); }

but to no avail, and I can not find anything on the Internet about this issue.

When tested with another program, such as Notepad, it has the desired behavior.

+4
source share
4 answers

MouseDown too late.

This is a workaround for sure, but there may be all you need:

private void txtInput_MouseMove(object sender, MouseEventArgs e)
{
    txtInput.Focus();
}

or of course:

txtInput.MouseMove += (s, e) => { txtInput.Focus(); }

, . , , , , .

+2

MouseDown MouseMove. Taw :

int start = 0;
private void richTextBox1_MouseDown(object sender, MouseEventArgs e)
{
    start = richTextBox1.GetTrueIndexPositionFromPoint(e.Location);
    richTextBox1.SelectionStart = start;
}

private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button.HasFlag(MouseButtons.Left))
    {
        var current = richTextBox1.GetTrueIndexPositionFromPoint(e.Location);
        richTextBox1.SelectionStart = Math.Min(current, start);
        richTextBox1.SelectionLength = Math.Abs(current - start);
    }
}

GetTrueIndexPositionFromPoint, Justin:

public static class RichTextBoxExtensions
{
    private const int EM_CHARFROMPOS = 0x00D7;
    public static int GetTrueIndexPositionFromPoint(this RichTextBox rtb, Point pt)
    {
        POINT wpt = new POINT(pt.X, pt.Y);
        int index = (int)SendMessage(new HandleRef(rtb, rtb.Handle), EM_CHARFROMPOS, 0, wpt);
        return index;
    }

    [DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, POINT lParam);
}
+2

, TextBox, , RichTextBox. , :

    private const int WM_PARENTNOTIFY = 0x0210;

    private Form Form = new Form(); // Your Form here!
    private RichTextBox RTB = new RichTextBox(); // Your RichTextBox here!

    protected override void WndProc(ref Message m) 
    {
        if ((m.Msg == WM_PARENTNOTIFY) && (Form != null) && (Form.Visible) && (GetChildAtPoint(PointToClient(Cursor.Position)) == RTB))
        {
            RTB.Focus();
        }

        base.WndProc(ref m);
    }

The WM_PARENTNOTIFY message can be sent several times (including when initializing the main form), so it is important to check that your form is not null, otherwise you will get an exception.

+1
source

It worked for me;

Extend RichTextBox and override WindowProc with this

protected override void WndProc(ref Message m) {
    const int WM_MOUSEACTIVATE = 0x21;

    if (m.Msg == WM_MOUSEACTIVATE) {
        // Take focus to enable click-through behavior for setting selection
        this.Focus();
    }

    // Let the base handle the event.
    base.WndProc(ref m);
}
0
source

All Articles