none
Showing cursor position in out of focus rich text box

    Question

  • With a normal rich text box when my application is in focus I get a flashing vertical bar showing me the position where the text will be inserted. (caret). When my application is out of focus then I can no longer see the flashing caret. Is there anyway I can do this so that my rich text box, even when my application is not the active application, shows the the caret at the text insertion point?

    Many thanks

    Using Windows Form / C#

    • Edited by scocia888 Sunday, October 02, 2011 8:04 PM
    Sunday, October 02, 2011 8:00 PM

Answers

  • test my code. i tried to create a custom dummy caret! Many mistakes may appear in my code; please, tell me to solve the mistakes!

    class CaretRichTextBox : RichTextBox
    {
        #region >>> Fields <<<
    
        Timer m_timer = new Timer();
    
        #endregion
    
        #region >>> Ctors <<<
    
        public CaretRichTextBox()
        {
            m_timer.Interval = (int)GetCaretBlinkTime();
            m_timer.Tick += tick;
        }
    
        #endregion
    
        #region >>> Methods <<<
    
        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);
    
            m_timer.Enabled = Visible;
        }
    
        protected override void DestroyHandle()
        {
            m_timer.Stop();
            base.DestroyHandle();
        }
    
        protected override void OnLostFocus(EventArgs e)
        {
            Point point;
            GetCaretPos(out point);
    
            if (BorderStyle != BorderStyle.None)
                point.X += 2;//we add 2 pixels for borders!
    
            LostCaretPosition = point;
    
    
            base.OnLostFocus(e);
            m_timer.Start();
        }
    
        protected override void OnGotFocus(EventArgs e)
        {
            m_timer.Stop();
            HideVirtualCaret();
            base.OnGotFocus(e);
        }
       
        private void tick(object obj, EventArgs e)
        {
            if (PrivateShowCaret)
            {
                ShowVirtualCaret();
            }
            else
            {
                HideVirtualCaret();
            }
            PrivateShowCaret = !PrivateShowCaret;
        }
    
        private void ShowVirtualCaret()
        {
            /*
             * my drawn caret is fully black when it's visible
             * windows use SRCINVERT when draw caret to invert
             * RGB to BGR. if you need to see how it work, you
             * can use LogoKey + (+) to open windows magnifier
             * to see how it!
             */
    
            using (Graphics g = Graphics.FromHwnd(Handle))
            {
                Color colorCaret = Color.Black;//default caret color!
    
                if (!PrivateShowCaret)
                {
    
                    colorCaret = BackColor;
                }
    
                using (Pen pen = new Pen(colorCaret, 1))
                {
                    g.DrawLine(pen, LostCaretPosition, new Point(LostCaretPosition.X, LostCaretPosition.Y + 10));
                }
            }
        }
    
        private void HideVirtualCaret()
        {
            Rectangle rectInvalidate = new Rectangle(LostCaretPosition, new Size(1, 11));
            Invalidate(rectInvalidate);//Invalidate only caret rectangle
        }
    
        #endregion
    
        #region >>> API <<<
    
        [DllImport("user32.dll", EntryPoint = "GetCaretPos")]
        public static extern bool GetCaretPos(out Point lpPoint);
    
        [DllImport("user32.dll")]
        public static extern uint GetCaretBlinkTime();
    
        #endregion
    
        #region >>> Properties <<<
    
        private bool PrivateShowCaret
        {
            get;
            set;
        }
        private Point LostCaretPosition
        {
            get;
            set;
        }
    
        #endregion
    }
    




    Any fool can know. The point is to understand.(Albert Einstein)
    • Marked as answer by scocia888 Monday, October 03, 2011 3:27 PM
    • Edited by Ehsan Mohammadi Monday, June 04, 2012 8:10 PM
    Sunday, October 02, 2011 11:54 PM

All replies

  • The system provides one caret per queue. A window should create a caret only when it has the keyboard focus or is active. The window should destroy the caret before losing the keyboard focus or becoming inactive.
    Any fool can know. The point is to understand.(Albert Einstein)
    Sunday, October 02, 2011 10:50 PM
  • test my code. i tried to create a custom dummy caret! Many mistakes may appear in my code; please, tell me to solve the mistakes!

    class CaretRichTextBox : RichTextBox
    {
        #region >>> Fields <<<
    
        Timer m_timer = new Timer();
    
        #endregion
    
        #region >>> Ctors <<<
    
        public CaretRichTextBox()
        {
            m_timer.Interval = (int)GetCaretBlinkTime();
            m_timer.Tick += tick;
        }
    
        #endregion
    
        #region >>> Methods <<<
    
        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);
    
            m_timer.Enabled = Visible;
        }
    
        protected override void DestroyHandle()
        {
            m_timer.Stop();
            base.DestroyHandle();
        }
    
        protected override void OnLostFocus(EventArgs e)
        {
            Point point;
            GetCaretPos(out point);
    
            if (BorderStyle != BorderStyle.None)
                point.X += 2;//we add 2 pixels for borders!
    
            LostCaretPosition = point;
    
    
            base.OnLostFocus(e);
            m_timer.Start();
        }
    
        protected override void OnGotFocus(EventArgs e)
        {
            m_timer.Stop();
            HideVirtualCaret();
            base.OnGotFocus(e);
        }
       
        private void tick(object obj, EventArgs e)
        {
            if (PrivateShowCaret)
            {
                ShowVirtualCaret();
            }
            else
            {
                HideVirtualCaret();
            }
            PrivateShowCaret = !PrivateShowCaret;
        }
    
        private void ShowVirtualCaret()
        {
            /*
             * my drawn caret is fully black when it's visible
             * windows use SRCINVERT when draw caret to invert
             * RGB to BGR. if you need to see how it work, you
             * can use LogoKey + (+) to open windows magnifier
             * to see how it!
             */
    
            using (Graphics g = Graphics.FromHwnd(Handle))
            {
                Color colorCaret = Color.Black;//default caret color!
    
                if (!PrivateShowCaret)
                {
    
                    colorCaret = BackColor;
                }
    
                using (Pen pen = new Pen(colorCaret, 1))
                {
                    g.DrawLine(pen, LostCaretPosition, new Point(LostCaretPosition.X, LostCaretPosition.Y + 10));
                }
            }
        }
    
        private void HideVirtualCaret()
        {
            Rectangle rectInvalidate = new Rectangle(LostCaretPosition, new Size(1, 11));
            Invalidate(rectInvalidate);//Invalidate only caret rectangle
        }
    
        #endregion
    
        #region >>> API <<<
    
        [DllImport("user32.dll", EntryPoint = "GetCaretPos")]
        public static extern bool GetCaretPos(out Point lpPoint);
    
        [DllImport("user32.dll")]
        public static extern uint GetCaretBlinkTime();
    
        #endregion
    
        #region >>> Properties <<<
    
        private bool PrivateShowCaret
        {
            get;
            set;
        }
        private Point LostCaretPosition
        {
            get;
            set;
        }
    
        #endregion
    }
    




    Any fool can know. The point is to understand.(Albert Einstein)
    • Marked as answer by scocia888 Monday, October 03, 2011 3:27 PM
    • Edited by Ehsan Mohammadi Monday, June 04, 2012 8:10 PM
    Sunday, October 02, 2011 11:54 PM
  • Absolutely awesome thank you! Works very well.
    Monday, October 03, 2011 3:27 PM
  • Very nice work-around code Ehsan.
    Mitja
    Monday, October 03, 2011 3:40 PM
  • Incidentally I took the liberty of modifying for different font sizes works absolutely beautifully and seamlessly. Many thanks once again.

       private void ShowVirtualCaret()
        {
            /*
             * my drawn caret is fully black when it's visible
             * windows use SRCINVERT when draw caret to invert
             * RGB to BGR. if you need to see how it work, you
             * can use LogoKey + (+) to open windows magnifier
             * to see how it!
             */
    
            using (Graphics g = Graphics.FromHwnd(Handle))
            {
                Color colorCaret = Color.Black;//default caret color!
    
                if (!PrivateShowCaret)
                {
    
                    colorCaret = BackColor;
                }
    
                using (Pen pen = new Pen(colorCaret, 1))
                {
                    g.DrawLine(pen, LostCaretPosition, new Point(LostCaretPosition.X, LostCaretPosition.Y + this.FontHeight ));
                }
            }
        }
    
        private void HideVirtualCaret()
        {
            Rectangle rectInvalidate = new Rectangle(LostCaretPosition, new Size(1, this.FontHeight ));
            Invalidate(rectInvalidate);//Invalidate only caret rectangle
        }
    
    



    Monday, October 03, 2011 4:16 PM
  • Thank you for reading my Replies!


    Any fool can know. The point is to understand.(Albert Einstein)
    Monday, October 03, 2011 5:48 PM