Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Blinking Cursor (IBeam) from a Read-Only RichTextBox

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;
like image 914
mrtaikandi Avatar asked Apr 09 '09 12:04

mrtaikandi


3 Answers

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

  private void Control_Enter(object sender, EventArgs e) {
    ActiveControl = null;
  }
like image 83
ChRoNoN Avatar answered Sep 22 '22 22:09

ChRoNoN


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);
        }
    }
}
like image 42
Pedro77 Avatar answered Sep 22 '22 22:09

Pedro77


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.

like image 20
Anirudh Goel Avatar answered Sep 25 '22 22:09

Anirudh Goel