RichTextBox 光标不断变为 IBeam

RichTextBox cursor keeps changing to IBeam

我有一个只读 RichTextBox,其光标设置为 Arrow。即便如此,当我悬停它时,光标会闪烁,并在 ArrowIBeam 之间快速切换。我怎样才能让它一直亮 Arrow 而不是闪烁?

我假设这是 WinForms 的 RichTextBox,因为 WPF 没有这个问题

RichTextBox 处理 WM_SETCURSOR 消息,如果鼠标指针在 Link 上结束,则将光标更改为 Cursors.Hand。开发人员的注释:

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 the WM_SETCURSOR implementation on Control to set it to the user's selection for the RichTextBox's cursor.

您可以设置当鼠标进入控件边界时捕获,然后当鼠标指针离开该区域时释放它。捕获需要释放,否则,当您第一次点击另一个控件时,光标将设置为 RichTextBox:

private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (!richTextBox1.ClientRectangle.Contains(e.Location)) {
        richTextBox1.Capture = false;
    }
    else if (!richTextBox1.Capture) {
        richTextBox1.Capture = true;
    }
}

Jimi 的回答可以很好地阻止闪烁,但我对在鼠标移动时捕获鼠标感觉不太好。例如,我在该解决方案中看到的一个问题是,如果您在鼠标移动时设置捕获,则键盘快捷键如 Alt+F4Alt+Space 将停止工作。

我更愿意处理 WndProc 并在收到时设置光标 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);
    }
}

它停止闪烁。这不是一个完美的解决方案,但至少那些重要的快捷方式将继续有效。