When you click on a text field, how to focus it, but don’t change the location of the cursor inside

I created an event handler for Textbox.Enter event , which selects a piece of text inside a text field, for example:
TextBox1.Select(3,5);

The result is as follows:

image.png

When a text field is entered through the keyboard using [Tab] or [Shift] - [Tab] ,
the part of the text to be selected is selected well, as in the screenshot above.

However, if the text field is entered not through the keyboard, but through the mouse,
then nothing is selected:

ts2.png

The following seems to be happening:

When we enter the text box with the mouse,
a click does raise the value of Enter event , but mouseclick also sets the location of the cursor to the location that the user clicked inside the text box.
And this cursor setting happens right after . The event handler has been started.

So, this means that the selection made by the event handler (with the line TextBox1.Select(3,5); ) is overridden by the location of the mouse,
and why entering the text box with the mouse seems to be picking nothing.

My question is:

How can I make the mouse really raise the Enter event , but not move the cursor position inside the text box?
Thus, I can make my choice (what happens in the code) and will not be redefined.

Edit:
The purpose of this is to provide easy selection of the MM: SS part, which is usually the edited part (the HH or mmm parts rarely change).

+5
source share
2 answers

I would like to suggest another way:

At the beginning of the Control.Enter event handler, I put this:

 while( (Control.MouseButtons&MouseButtons.Left)!=0 ) Application.DoEvents(); 

It just waits for the left mouse button to click.

Only when releasing the left mouse button we continue the next line of code, which

 TextBox1.Select(3,5); 

and then it works well - the choice takes place without redefinition.

+1
source

A slightly strange request, but if you really want it, you can use the well-known general method of scheduling an action that will be performed later (after normal processing of Windows messages / events) using Control.BeginInvoke .

Something like that

 void textBox_Enter(object sender, EventArgs e) { BeginInvoke(new Action(() => textBox.Select(3, 5))); } 

Update:. According to your comment, if you want to prevent the default mouse behavior, you need to handle WM_MOUSEACTIVATE by creating and using your own TextBox subclass like this

 class MyTextBox : TextBox { protected override void WndProc(ref Message m) { const int WM_LBUTTONDOWN = 0x0201; const int WM_MOUSEACTIVATE = 0x0021; const int MA_ACTIVATEANDEAT = 2; const int MA_NOACTIVATEANDEAT = 4; if (m.Msg == WM_MOUSEACTIVATE && !Focused) { int mouseMsg = unchecked((int)((uint)(int)m.LParam >> 16)); // LOWORD(m.LParam) if (mouseMsg == WM_LBUTTONDOWN) { bool activated = Focus(); m.Result = (IntPtr)(activated ? MA_ACTIVATEANDEAT : MA_NOACTIVATEANDEAT); return; } } base.WndProc(ref m); } } 
+2
source

Source: https://habr.com/ru/post/1239718/


All Articles