Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RichTextBox doesn't start selection on mouse down when the form has not focus

I'm using WinForms and on my Form I have a RichTextBox. When my form is out of focus but visible and I try to highlight/select text, it does not allow me to until the form or textbox itself has focus.

I've tried:

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

but to no avail and I can't seem to find anything online about this issue.

When testing with another program like Notepad, it does possess the desired behavior.

like image 861
Walter Bishop Avatar asked Apr 21 '16 17:04

Walter Bishop


2 Answers

MouseDown is too late.

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

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

or of course:

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

As it is it may steal focus from other controls on your form when you move over the textbox. If this is a problem you could prevent it by checking if your program is active using one the of answers here..

like image 90
TaW Avatar answered Sep 25 '22 14:09

TaW


You can make the selection manually using MouseDown and MouseMove events. The answer is based on Taw's first idea:

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

And here is the codes for GetTrueIndexPositionFromPoint method which has taken from 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);
}
like image 20
Reza Aghaei Avatar answered Sep 25 '22 14:09

Reza Aghaei