Windows Forms Textbox: Selection and Caret position - c#

After setting the SelectionStart and SelectionLength, the Caret is at the end of the selection.
How can I move the Caret to the beginning of the selection?
I now tried this: The question is not answered by the other threads
SelectionStart = selStart; // set the desired position
SelectionLength = 0;
MyLibs.WindowsDll.POINT point;
MyLibs.WindowsDll.GetCaretPos(out point); // save the position
SelectionLength = restOfWord.Length; // extend the selection
MyLibs.WindowsDll.SetCaretPos(point.X, point.Y); // restore caret position
GetCaretPos and SetCaretPos are working somehow, but not as it should.
Using the above code snippet, the caret is indeed blinking at the beginning of the selection.
But ... then I hit backspace or cursor left/right, the caret still behaves like it is still at the end of the selection.

Unfortunately, you can not do this using managed code like C#,
but to achieve this goal you may use C++, SetFocus() function,
for example:
//use SetFocus()
pEdit->SetFocus()
//place caret at the end:
pEdit->SendMessage (WM_KEYDOWN,VK_END,0);
//simulate keyup:
m_Edit->SendMessage (WM_KEYUP,VK_END,0);
//send the key code:
m_Edit->SendMessage(WM_CHAR,'A',0);
Have a look to MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646312(v=vs.85).aspx
You may use also CEdit::SetSel to accomplish that:
CEdit* e = (CEdit*)GetDlgItem(IDC_EDIT1);
e->SetFocus();
e->SetSel(0,-1); // move cursor at the end
e->SetSel(-1); // remove selection
See details in Stackoverflow question: CEdit control MFC, placing cursor to end of string after SetWindowText
UPDATED:
If you need to set position to the beginning you can reset the Caret position to start before displaying the text using:
SetSel (0,0);
You can not move the caret to the beginning while keeping the text selected using basic C#/C++ functions, however you can override basic "Caret" logic using C++ or/and Assembler.

Related

Move caret to start and end of line in a RichEditBox

I've a RichEditBox that I'd like to add keyboard shortcut support to enable moving to the start or the end of the line that the caret is currently on. I've already figured out shortcuts supporting going to start or end of sentence as that involved simply reviewing the text value of the content and finding the nearest period. However, I believe what I'm looking for now is more involved as it requires working through the raw content of the file, which I'm not comfortable with nor have managed to find any resources with the guidance I'm after (I've mostly found answers on detecting the EOL character type rather than moving the caret to the EOL).
If you want to move caret, we can use the RichEditBox.Document.Selection.Move method to move the insertion point forward or backward by the specified number of units.
We can set TextRangeUnit.Line to the Move method, it will move caret to start or end of line in a RichEditBox.
For example:
myRichEdit.Document.Selection.Move(TextRangeUnit.Line, 1);

How to set Selection start based on Mouse Position WinForms

I need to set Selection start of a text box based on the mouse position, i tried to load the text box on Double Click, once the text box is loaded, i need to set the selection start based on the Mouse position. (i.e) if a text box contains some values like "abcdef", if the mouse cursor is near "c" when textbox is loaded, then the selection start should be after "c".
I have also tried this
textBox.GetCharIndexFromPosition(e.Location);
but i didn't get it right,
Thanks in advance.
Regards,
Venkatesan R
Putting #Reza's code in the correct event will work just fine:
private void textBox_MouseDoubleClick(object sender, MouseEventArgs e)
{
textBox.Text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // load the text data here
// now position the caret onto the mouse position
textBox.SelectionStart = textBox.GetCharIndexFromPosition(e.Location);
// and clear a selection
textBox.SelectionLength = 0;
}
Note that you need to use the MouseDoubleClick, not the simple DoubleClick or else you miss the e.Location param!
This is the simplest and most direct way to get the mouse coordinates relative to the TextBox.
If your loading method is complex you can call it by passing in the MouseEventArgs e but simply calling it instead of the textBox.Text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; is the most natural way.
If you want to you could also use
textBox.SelectionStart = textBoxtextBox1.PointToClient(Control.MousePosition));
This will work in any event or method. PointToClient will calulate the relative position from the screen position Control.MousePosition.

RichTextBox.GetLineFromCharIndex does not work correctly. How to get the CORRECT line index in which the cursor currently is?

I'm trying to find a way to get the line's index in which the cursor is currently blinking in a RichTextBox control, and display it in a Label.
First I've tried GetLineFromCharIndex(), but when I press an arrow key, it does not updates itself at the first time. I've created this example:
These are my lines:
this
is
my
example
when I wrote these, the line index was shown correctly. Now let's say my cursor is blinking right now in the fourth line (I = the cursor)
this
is
my
eIxample
The index is now correctly displayed as 3. But now if I press an up arrow key, the cursor will blink in the "my" line, but the index will be still 3.
If I write the indexes every time I pressed the up key to the console, the result looks like this:
//Output:
3
3
2
1
I've tried to use Regex and a foreach loop as well, but they gave me the perfectly same result.
Can anyone give me a good advice how to write a code that always updates and shows the correct index of the line in which the cursor currently is?
Thanks
You are probably handling the KeyDown event of RichTextBox, which fires before the SelectionStart property is changed to the cursor position, so that method always gives you the line index for the previous cursor position. Handle the KeyUp event and your problem should be fixed:
private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
{
int selectionStart = richTextBox1.SelectionStart;
int lineIndex = richTextBox1.GetLineFromCharIndex(selectionStart);
label1.Text = lineIndex.ToString();
}

Logic of RichTextBox.Paste() method

What is the internal logic of RichTextBox.Paste() method which pastes data from clipboard to RichTextBox.
Actually I want to add text to RichTextBox at the location where cursor is there on button click. But when I add text the added text is either selected after addition or the cursoe location is at the start of added text.
Any solution for this ?
I think you don't need to know the .NET implementation of the control. It is "black box" for you and me. But, you can do unselect and move cursor to the end of text (this 2 things disturb you, not?)
Moving cursor to position 0 (start):
richTextBox1.Select(0, 0);
Moving to the end:
richTextBox1.Select(richTextBox1.Text.Length, 0);
Select all text:
richTextBox1.Select(0, richTextBox1.Text.Length);
Unselect all and move to the end:
richTextBox1.Select(richTextBox1.Text.Length, richTextBox1.Text.Length);

How can I get the insertion position of a TextBox when there is a selection?

If there is no selection in a TextBox, then the insertion position is equal to SelectionStart.
But if there is a Selection, then the insertion position might be at SelectionStart (right-to-left selection):
Or it might be at SelectionStart + SelectionLength (left-to-right selection):
How, then, does one figure out the insertion position of a TextBox when there is a selection?
There could be a way to trick, but there is no natural way of doing that.
If for example at given moment in application you know that the text in TextBox is selected (no difference left-right or right-left),
you can do
textBox1.SelectionLength = 0; //this will clear a selection UI
After this line by calling
int caretPosition = textBox1.SelectionStart;
will retrieve actually a Caret position to you.
By the way this is a trick, so it's better to avoid these kind of solutions (may be there will be someone offering something else) and it's better to slightly rearrange the code.
Hope this helps.
Great explanation on caret position here, best to call native API that way you don't break selection and other textbox functions (such as undo)
http://www.microbion.co.uk/developers/C%20position%20of%20caret.pdf

Categories

Resources