I have a readonly RichTextBox
, with its cursor set to Arrow
. Even so, when I hover it, the cursor flickers, and switches very quickly between Arrow
and IBeam
. How can I make it stay on Arrow
and not flicker?

- 4,555
- 31
- 31
- 45

- 4,085
- 7
- 42
- 82
2 Answers
Jimi's answer works well to stop flickering, but I don't have a good feeling about capturing mouse on mouse move. For example one issue that I see in that solution, is if you set the capture on mouse move, then keyboard shortcuts like Alt+F4 or Alt+Space will stop working.
I'd prefer to handle WndProc
and set the cursor when received WM_SETCURSOR
:
using System.Windows.Forms;
public class ExRichTextBox : RichTextBox
{
const int WM_SETCURSOR = 0x0020;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SETCURSOR)
Cursor.Current = this.Cursor;
else
base.WndProc(ref m);
}
}
It stops flickering. Not a perfect solution, but at least those important shortcuts will continue working.

- 120,393
- 18
- 203
- 398
-
Why is it not perfect? – Michael Haddad Feb 08 '19 at 10:57
-
1For example when you hover on links, it doesn't show hand. – Reza Aghaei Feb 08 '19 at 10:58
-
1Well, from my experience in StackOverflow, you are one of the best WinForms experts on this site (which probably means that you are one of the bests in the world). So I believe in your ability to help the WinForms community with this REALLY important question. :D – Michael Haddad Feb 08 '19 at 11:02
-
Yes, this is why I do not change the accepted answer. Jimi's answer works just fine for me. – Michael Haddad Feb 08 '19 at 11:05
-
1No need to change at all, unless a perfect answer is shared. I also didn't meant to affect the other answer and the other answer has my vote as well. Just shared another alternative. Specially in case some one wants to have Alt+F4 working even when the mouse is over richtextbox. – Reza Aghaei Feb 08 '19 at 11:08
-
Maybe playing with what is passed (back and forth) when [`DefWndProc` is called](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/RichTextBox.cs,3669). It takes *some* testing, though. – Jimi Feb 08 '19 at 11:12
I'm assuming this is the WinForms' RichTextBox, because the WPF one doesn't have this problem.
The RichTextBox handles WM_SETCURSOR
messages, to change the Cursor to Cursors.Hand
if the Mouse Pointer ends up on a Link. A note from the developers:
RichTextBox uses the
WM_SETCURSOR
message over links to allow us to change the cursor to a hand. It does this through a synchronous notification message. So we have to pass the message to the DefWndProc first, and then, if we receive a notification message in the meantime (indicated by changing "LinkCursor", we set it to a hand. Otherwise, we call theWM_SETCURSOR
implementation on Control to set it to the user's selection for the RichTextBox's cursor.
You could set the Capture when the Mouse enters the Control's bounds and then release it when the Mouse Pointer leaves the area. The capture needs to be released otherwise, when you first click on another control, the cursor will be set to RichTextBox instead:
private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
if (!richTextBox1.ClientRectangle.Contains(e.Location)) {
richTextBox1.Capture = false;
}
else if (!richTextBox1.Capture) {
richTextBox1.Capture = true;
}
}

- 29,621
- 8
- 43
- 61
-
Thanks! It works, until the user clicks on it, then it starts to flicker again. – Michael Haddad Feb 08 '19 at 09:39
-
-
1I have noticed something. When I hover the mouse over the edges of the `RichTextBox`, the IBeam sometimes appear again for a fraction of a second. Perhaps it's negligible for some people, but it drives me crazy. :D I have tried to capture my screen to show it, but it is so fast that even with 60fps I don't manage to capture it... – Michael Haddad Feb 08 '19 at 10:28
-
I can't reproduce it, but it may depend on the `ClientRectangle` size. Try to enlarge it: `Rectangle rect = richTextBox1.ClientRectangle; rect.Inflate(4, 4); if (!rect.Contains(e.Location)) (...)` – Jimi Feb 08 '19 at 10:45
-
Didn't work... However, when I remove the condition and simply write `richTextBox1.Capture = true;` it works. Why do we actually need the condition? – Michael Haddad Feb 08 '19 at 10:53
-
1The reason why you need to release the Capture is explained in the answer. See also what Reza Aghaei wrote. The Capture needs to be released when the Mouse pointer leaves the Control's area, otherwise it generates some mis-behaviours. This is also explained. If you decide to use a Custom Control, see also this: [How to justify text in a label](https://stackoverflow.com/a/47470191/7444103). Among the other things, there's a custom RichTextBox that supports Block Align (also known as Full justification). Maybe you have some use for it. – Jimi Feb 08 '19 at 11:01
-
Your comment helped me understand better what you meant in your answer. Thank you! – Michael Haddad Feb 08 '19 at 11:03
-
1@Jimi My comment about capturing is, while you are release the capture when the mouse is outside the control, but when the mouse is over richtextbox, Alt+F4 will not work, because richtextbox has the capture. It's not about releasing capture when mouse leaves. – Reza Aghaei Feb 08 '19 at 11:15
-
1@Reza Aghaei Yes, I know what you meant. My comment was about enforcing the need to release the capture, because the OP was apparently deciding to use just `richTextBox1.Capture = true;` in the event handler. – Jimi Feb 08 '19 at 11:18