【发布时间】:2022-01-19 00:55:17
【问题描述】:
我有一个只读的RichTextBox,其光标设置为Arrow。尽管如此,当我将它悬停时,光标会闪烁,并在Arrow 和IBeam 之间快速切换。我怎样才能让它留在Arrow而不闪烁?
【问题讨论】:
标签: c# winforms richtextbox mouse-cursor
我有一个只读的RichTextBox,其光标设置为Arrow。尽管如此,当我将它悬停时,光标会闪烁,并在Arrow 和IBeam 之间快速切换。我怎样才能让它留在Arrow而不闪烁?
【问题讨论】:
标签: c# winforms richtextbox mouse-cursor
我假设这是 WinForms 的 RichTextBox,因为 WPF 没有这个问题。
RichTextBox 处理WM_SETCURSOR 消息,如果鼠标指针最终位于链接上,则将光标更改为Cursors.Hand。开发人员的说明:
RichTextBox 在链接上使用
WM_SETCURSOR消息,让我们能够 将光标更改为手形。它通过同步 通知消息。所以我们必须将消息传递给 DefWndProc 首先,然后,如果我们在此期间收到通知消息 (通过更改“LinkCursor”表示,我们将其设置为手。否则, 我们调用 Control 上的WM_SETCURSOR实现将其设置为 用户对 RichTextBox 光标的选择。
您可以在鼠标进入控件的边界时设置捕获,然后在鼠标指针离开该区域时释放它。否则需要释放捕获,当您第一次单击另一个控件时,光标将设置为 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;
}
}
【讨论】:
RichTextBox 的边缘时,IBeam 有时会再次出现几分之一秒。也许对某些人来说可以忽略不计,但它让我发疯。 :D 我试图捕捉我的屏幕来显示它,但它太快了,即使是 60fps 我也无法捕捉到它......
richTextBox1.Capture = true;。
Jimi 的回答可以很好地停止闪烁,但我对在鼠标移动时捕获鼠标感觉不太好。例如,我在该解决方案中看到的一个问题是,如果您在鼠标移动时设置捕获,那么像 Alt+F4 或 Alt这样的键盘快捷键>+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);
}
}
它停止闪烁。不是一个完美的解决方案,但至少那些重要的快捷方式将继续有效。
【讨论】: