防止只读 RichTextBox 出现闪烁光标 (IBeam)

发布于 2024-07-16 23:27:20 字数 201 浏览 4 评论 0原文

每当文本框获得焦点时,是否有办法防止只读 RichRextBox 的光标(IBeam)闪烁?

我尝试阻止来自 WndProcWM_SETFOCUS 消息,但它导致表单挂起。

if( m.Msg == 0x0007 ) return;

Is there anyway to prevent the cursor (IBeam) of a read-only RichRextBox from blinking whenever the textbox got focus?

I've tried to block the WM_SETFOCUS message from the WndProc but it causes the form to hang.

if( m.Msg == 0x0007 ) return;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

红玫瑰 2024-07-23 23:27:20

您需要使用 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)

然后在您想要隐藏它时

You'll need to use Win32 APIs. Here's what you could do in 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)

and in 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);

then make a call to

   HideCaret(richtextbox.Handle)

when ever you want to hide it.

柠栀 2024-07-23 23:27:20

只是说 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);
        }
    }
}

Just to say that the Anirudh Goel answer does not work (at least in C#). The carat still there blinking :/

I found a solution at: http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21896403.html

His class always hide the caret, here is an improved one so you can choose to hide or not the caret.

If you want to hide do not forget to set MustHideCaret to 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);
        }
    }
}
能怎样 2024-07-23 23:27:20

更简单的方法:将此事件附加到 RichTextBox 的 Enter 事件中:

  private void Control_Enter(object sender, EventArgs e) {
    ActiveControl = null;
  }

Easier method: attach this event to the Enter event of the RichTextBox:

  private void Control_Enter(object sender, EventArgs e) {
    ActiveControl = null;
  }
简单爱 2024-07-23 23:27:20

对我来说 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 放入(内部)面板控件中...
修复了单击鼠标时闪烁插入符号的问题...

For me solution from Pedro77 didn't work too...
I've modified that class to:

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);
        }
    }
}

then put my RichTextBoxEx into (inside) Panel control...
that fixed getting blinking caret on mouse click...

雪落纷纷 2024-07-23 23:27:20

经过多次尝试和错误,我找到了简单的解决方案。

在表单的“加载”子例程中,添加以下行:

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 不是很棒吗? 你几乎可以实现任何你认为不可能的事情。

After much trial and error, I have found the simple solution.

In your form's "Load" subroutine, add the line:

AddFocusHandlers(Me)

Then add to the bottom of your form's code the following. Stipulate the controls on which you wish this "blocking of entry" to occur in the "HideCaret" routine
(I have listed three textboxes belonging to my form):

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

and finally place at the top of your form code (between the Class name and the first sub or function the following:

    Private LastFocused As Control  'Control which previously had focus

Then when the user clicks on any control shown in the list of controls in the "HideCaret" routine, the cursor simply stays in the previously selected control.
Isn't VB.Net wonderful? You can achieve almost anything you thought not possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文