防止从只读RichTextBox中闪烁光标(IBeam)

时间:2022-09-11 17:44:50

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

无论如何,只要文本框得到焦点,就会阻止只读RichRextBox的光标(IBeam)闪烁?

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

我试图阻止来自WndProc的WM_SETFOCUS消息,但它导致表单挂起。

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

4 个解决方案

#1


You'll need to use Win32 APIs. Here's what you could do in VB:

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

and in C#

在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.

什么时候你想隐藏它。

#2


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

只是说Anirudh Goel的答案不起作用(至少在C#中)。克拉仍然闪烁着:/

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

我找到了一个解决方案: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

如果你想隐藏,别忘了将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);
        }
    }
}

#3


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

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

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

#4


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

对我来说,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);
        }
    }
}

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

然后将我的RichTextBoxEx放入(内部)Panel控件中...修复了鼠标点击时闪烁的插入符号...

#1


You'll need to use Win32 APIs. Here's what you could do in VB:

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

and in C#

在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.

什么时候你想隐藏它。

#2


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

只是说Anirudh Goel的答案不起作用(至少在C#中)。克拉仍然闪烁着:/

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

我找到了一个解决方案: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

如果你想隐藏,别忘了将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);
        }
    }
}

#3


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

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

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

#4


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

对我来说,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);
        }
    }
}

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

然后将我的RichTextBoxEx放入(内部)Panel控件中...修复了鼠标点击时闪烁的插入符号...