Select current RichTextBox row

This emphasizes the entire width of each line, drawing a transparent color as the backlight of the current line. When the line is switched, the original background color is restored.

So we want to do the following:

  • Make sure that the previous and current rectangles do not match, so as not to draw the same area twice
  • Replace last line selection with inverse color controls
  • Highlight the current line with a transparent color.
  • Set mLastHighlightwith index and rectangle for each row applied

However, when the backlight is removed, the text is colored. This does not occur when applying the selection.

One solution would be to repaint the text back to the control after resetting the background. although text formatting, selection colors, font styles, hyperlinks, etc. would be tedious for filtering. Not very elegant.

This leads to a simpler solution, refreshing management. Although this will cause massive flicker. Unacceptably.

Is there an elegant solution? I am completely puzzled why this is happening.

EDIT : Edited to display Gray code response.

using System;

public class RTBHL : RichTextBox
{
    private LastHighlight mLastHighlight = new LastHighlight(0, Rectangle.Empty);

    private class LastHighlight
    {
        public int mCharIndex;
        public Rectangle mRectangle;

        public LastHighlight(int index, Rectangle r)
        {
            mCharIndex = index;
            mRectangle = r;
        }
    }

    public void PaintLineHighlight()
    {
        using (Graphics g = this.CreateGraphics)
        {
            // highlight color
            Color c = Color.Beige;
            // current pen color
            Pen cp = new Pen(Color.Beige);
            // color for removing highlight
            Pen lp = new Pen(this.BackColor);
            // brush for removing highlight
            SolidBrush lb = new SolidBrush(this.BackColor);
            // brush for applying highlight
            SolidBrush cb = new SolidBrush(Color.FromArgb(64, c.R, c.G, c.B));
            // index of the current line
            int index = this.GetFirstCharIndexOfCurrentLine;
            // rectangle to specify which region to paint too
            Rectangle r = new Rectangle();

            // specify dimensions
            r.X = 0;
            r.Y = this.GetPositionFromCharIndex(index).Y;
            r.Width = this.HorizontalScrollBarWidth;
            r.Height = Convert.ToInt32(this.Font.Height * this.ZoomFactor);

            // this will always be true unless the current line remains the same
            if (!(mLastHighlight.mCharIndex == index) && !(mLastHighlight.mRectangle == r))
            {
                // remove the last highlight. regardless of the brush specified, white is always applied, and the text is painted over
                g.DrawRectangle(lp, mLastHighlight.mRectangle);
                g.FillRectangle(lb, mLastHighlight.mRectangle);
                // apply highlight to the current line
                g.DrawRectangle(cp, r);
                g.FillRectangle(cb, r);
            }

            mLastHighlight = new LastHighlight(index, r);
        }
    }

#region RichScrollBars
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, ref SCROLLINFO si);

    [StructLayout(LayoutKind.Sequential)]
    public class SCROLLINFO
    {
        public int cbSize;
        public int fMask;
        public int nMin;
        public int nMax;
        public int nPage;
        public int nPos;
        public int nTrackPos;
        public SCROLLINFO()
        {
            this.cbSize = Marshal.SizeOf(typeof(SCROLLINFO));
        }

        public SCROLLINFO(int mask, int min, int max, int page, int pos)
        {
            this.cbSize = Marshal.SizeOf(typeof(SCROLLINFO));
            this.fMask = mask;
            this.nMin = min;
            this.nMax = max;
            this.nPage = page;
            this.nPos = pos;
        }
    }

    private const int SIF_ALL = 0X17;
    private const int SB_HORZ = 0;
    private const int SB_VERT = 1;

    public int HorizontalScrollBarWidth()
    {
        SCROLLINFO si = new SCROLLINFO() {fMask = SIF_ALL};
        GetScrollInfo(this.Handle, SB_HORZ, si);

        return Math.Max(si.nMax, this.Width);
    }

    public int VerticalScrollBarHeight()
    {
        SCROLLINFO si = new SCROLLINFO() {fMask = SIF_ALL};
        GetScrollInfo(this.Handle, SB_VERT, si);

        return Math.Max(si.nMax, this.Height);
    }
#endregion
}
+5
source share
1 answer

, , , Scintilla. SCI_* Scintilla, , , Scintilla.

Win32 rich , . (, , SCI_* , , .)

Scintilla (, , ), . Win32, Scintilla.

Scintilla - , Win32. , , . Scintilla . , .

, , Win32. , , . , , , . - . Scintilla, Scintilla, Win32 ( .NET WinForms).

+3

All Articles