-3

I'm doing a text editor based on RichTextBox. It has to handle complex formatting (BIU, colored text, etc). The problem is that all formatting tools are selection based, e.g. i have to select piece of text, format it, select next, etc.

it takes time, and it is visible for user.

is there a way to turn-off RichTextBox redraw, then do formatting, then turn-on redraw?

Or maybe any other way to handel complex formatting quickly?

Fedor Pinega
  • 73
  • 1
  • 8
  • 3
    See [RichTextBox flickers while coloring words](https://stackoverflow.com/a/29038498/719186) – LarsTech Feb 18 '21 at 19:46
  • 2
    RichTextBox is not an exactly meant to be a complex text editor. You can get [Scintilla .NET](https://github.com/jacobslusser/ScintillaNET) (or similar) for that. – Jimi Feb 18 '21 at 19:54

1 Answers1

0

Decision found and it's working.

Wrote a wrap-class using this code

Class itself:

  public class RichTextBoxRedrawHandler
{
    RichTextBox rtb;

    public RichTextBoxRedrawHandler (RichTextBox _rtb)
        {
        rtb = _rtb;
        }
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, int wParam, ref Point lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, int wParam, IntPtr lParam);

    const int WM_USER = 1024;
    const int WM_SETREDRAW = 11;
    const int EM_GETEVENTMASK = WM_USER + 59;
    const int EM_SETEVENTMASK = WM_USER + 69;
    const int EM_GETSCROLLPOS = WM_USER + 221;
    const int EM_SETSCROLLPOS = WM_USER + 222;

    private Point _ScrollPoint;
    private bool _Painting = true;
    private IntPtr _EventMask;
    private int _SuspendIndex = 0;
    private int _SuspendLength = 0;

    public void SuspendPainting()
    {
        if (_Painting)
        {
            _SuspendIndex = rtb.SelectionStart;
            _SuspendLength = rtb.SelectionLength;
            SendMessage(rtb.Handle, EM_GETSCROLLPOS, 0,  ref _ScrollPoint);
            SendMessage(rtb.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
            _EventMask = SendMessage(rtb.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
            _Painting = false;
        }
    }

    public void ResumePainting()
    {
        if (!_Painting)
        {
            rtb.Select(_SuspendIndex, _SuspendLength);
            SendMessage(rtb.Handle, EM_SETSCROLLPOS, 0, ref _ScrollPoint);
            SendMessage(rtb.Handle, EM_SETEVENTMASK, 0, _EventMask);
            SendMessage(rtb.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
            _Painting = true;
            rtb.Invalidate();
        }

    }
}

Usage:

RichTextBoxRedrawHandler rh = new RichTextBoxRedrawHandler(richTextBoxActually);
rh.SuspendPainting();
// do things with richTextBox
rh.ResumePainting();
Fedor Pinega
  • 73
  • 1
  • 8