【发布时间】:2021-04-14 13:54:38
【问题描述】:
是否有办法防止只读RichRextBox 的光标(IBeam)在文本框获得焦点时闪烁?
我试图阻止来自WndProc 的WM_SETFOCUS 消息,但这会导致表单挂起。
if( m.Msg == 0x0007 ) return;
【问题讨论】:
标签: winforms richtextbox
是否有办法防止只读RichRextBox 的光标(IBeam)在文本框获得焦点时闪烁?
我试图阻止来自WndProc 的WM_SETFOCUS 消息,但这会导致表单挂起。
if( m.Msg == 0x0007 ) return;
【问题讨论】:
标签: winforms richtextbox
您需要使用 Win32 API。以下是您可以在 VB 中执行的操作:
'API declares
Private Declare Function HideCaret Lib "user32" _
(ByVal hwnd As IntPtr) As Integer
Private Declare Function ShowCaret Lib "user32" _
(ByVal hwnd As IntPtr) As Integer
'hide the caret in myTextBox
Call HideCaret(myTextBox.Handle)
'show the caret back..
Call ShowCaret(myTextBox.Handle)
在 C# 中
[DllImport("user32.dll", EntryPoint = "ShowCaret")]
public static extern long ShowCaret(IntPtr hwnd);
[DllImport("user32.dll", EntryPoint = "HideCaret")]
public static extern long HideCaret(IntPtr hwnd);
然后拨打电话
HideCaret(richtextbox.Handle)
当你想隐藏它时。
【讨论】:
textbox.GotFocus中调用它时发现成功了@
只是说 Anirudh Goel 的答案不起作用(至少在 C# 中)。克拉还在那里闪烁:/
我找到了解决方案:http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21896403.html
他的班级总是隐藏插入符号,这里有一个改进的,因此您可以选择隐藏或不隐藏插入符号。
如果你想隐藏不要忘记将 MustHideCaret 设置为 true
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Lm
{
public class RichTextBoxEx : RichTextBox
{
private readonly object mustHideCaretLocker = new object();
private bool mustHideCaret;
[DefaultValue(false)]
public bool MustHideCaret
{
get
{
lock (this.mustHideCaretLocker)
return this.mustHideCaret;
}
set
{
TabStop = false;
if (value)
SetHideCaret();
else
SetShowCaret();
}
}
[DllImport("user32.dll")]
private static extern int HideCaret(IntPtr hwnd);
[DllImport("user32.dll", EntryPoint = "ShowCaret")]
public static extern long ShowCaret(IntPtr hwnd);
public RichTextBoxEx()
{
}
private void SetHideCaret()
{
MouseDown += new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
MouseUp += new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
Resize += new EventHandler(ReadOnlyRichTextBox_Resize);
HideCaret(Handle);
lock (this.mustHideCaretLocker)
this.mustHideCaret = true;
}
private void SetShowCaret()
{
try
{
MouseDown -= new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
MouseUp -= new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
Resize -= new EventHandler(ReadOnlyRichTextBox_Resize);
}
catch
{
}
ShowCaret(Handle);
lock (this.mustHideCaretLocker)
this.mustHideCaret = false;
}
protected override void OnGotFocus(EventArgs e)
{
if (MustHideCaret)
HideCaret(Handle);
}
protected override void OnEnter(EventArgs e)
{
if (MustHideCaret)
HideCaret(Handle);
}
private void ReadOnlyRichTextBox_Mouse(object sender, System.Windows.Forms.MouseEventArgs e)
{
HideCaret(Handle);
}
private void ReadOnlyRichTextBox_Resize(object sender, System.EventArgs e)
{
HideCaret(Handle);
}
}
}
【讨论】:
更简单的方法:将此事件附加到 RichTextBox 的 Enter 事件中:
private void Control_Enter(object sender, EventArgs e) {
ActiveControl = null;
}
【讨论】:
对我来说,Pedro77 的解决方案也不起作用...... 我已将该类修改为:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Lm
{
public class RichTextBoxEx : RichTextBox
{
private readonly object mustHideCaretLocker = new object();
private bool mustHideCaret;
[DefaultValue(false)]
public bool MustHideCaret
{
get
{
lock (this.mustHideCaretLocker)
return this.mustHideCaret;
}
set
{
TabStop = false;
if (value)
SetHideCaret();
else
SetShowCaret();
}
}
[DllImport("user32.dll")]
private static extern int HideCaret(IntPtr hwnd);
[DllImport("user32.dll", EntryPoint = "ShowCaret")]
public static extern long ShowCaret(IntPtr hwnd);
public RichTextBoxEx()
{
}
private void SetHideCaret()
{
MouseDown += new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
MouseUp += new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
Resize += new EventHandler(ReadOnlyRichTextBox_Resize);
HideCaret(Handle);
lock (this.mustHideCaretLocker)
this.mustHideCaret = true;
}
private void SetShowCaret()
{
try
{
MouseDown -= new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
MouseUp -= new MouseEventHandler(ReadOnlyRichTextBox_Mouse);
Resize -= new EventHandler(ReadOnlyRichTextBox_Resize);
}
catch
{
}
ShowCaret(Handle);
lock (this.mustHideCaretLocker)
this.mustHideCaret = false;
}
protected override void OnGotFocus(EventArgs e)
{
if (MustHideCaret)
{
HideCaret(Handle);
this.Parent.Focus();//here we select parent control in my case it is panel
}
}
protected override void OnEnter(EventArgs e)
{
if (MustHideCaret)
HideCaret(Handle);
}
private void ReadOnlyRichTextBox_Mouse(object sender, System.Windows.Forms.MouseEventArgs e)
{
HideCaret(Handle);
}
private void ReadOnlyRichTextBox_Resize(object sender, System.EventArgs e)
{
HideCaret(Handle);
}
}
}
然后将我的 RichTextBoxEx 放入(内部)面板控件... 修复了鼠标单击时插入符号闪烁的问题...
【讨论】:
经过多次尝试和错误,我找到了简单的解决方案。
在表单的“加载”子例程中,添加以下行:
AddFocusHandlers(Me)
然后将以下内容添加到表单代码的底部。在“HideCaret”例程中规定您希望此“阻止进入”发生的控件 (我列出了属于我的表单的三个文本框):
Private Sub AddFocusHandlers(ByVal parentCtr As Control)
Dim ctr As Control
For Each ctr In parentCtr.Controls
AddHandler ctr.LostFocus, AddressOf meLostFocus
AddFocusHandlers(ctr)
Next
End Sub
Private Sub meLostFocus(ByVal sender As Object, ByVal e As System.EventArgs)
LastFocused = DirectCast(sender, Control)
End Sub
'This routine will activate each time any of the listed controls are entered.
Private Sub HideCaret(sender As Object, e As EventArgs) _
Handles tbDate.Enter, tbAttachments.Enter, tbTemplate.Enter
LastFocused.Select()
End Sub
最后放置在表单代码的顶部(在类名和第一个子或函数之间:
Private LastFocused As Control 'Control which previously had focus
然后,当用户单击“HideCaret”例程中控件列表中显示的任何控件时,光标只会停留在先前选择的控件中。 VB.Net 不是很棒吗?您几乎可以实现您认为不可能的任何事情。
【讨论】: