• 0

C# richtextbox prevent autoscrolling with select() method?


Question

Hi,

I've created a syntax highlighting text editor that only updates the text that is visible at the time.

I've implemented the VScroll event so that the syntax highlighting updates when new text is scrolled into view. I highlight each keyword by select()'ing it, modifying the selectionfont, selectioncolor, etc properties, and then select()'ing back to the original caret position. select() causes the scrollbar to move, which causes a lot of flicker and actually stops me from using the richtextbox control.

One solution would be to just update the entire control rather than only the visible area, but with large documents this causes flickering.

Does anyone have any idea how I can select() text in the richtextbox without it automatically scrolling the contents?

Thanks!

2 answers to this question

Recommended Posts

  • 0
  On 08/02/2011 at 23:48, figgy said:

You may use LockWindowUpdate Windows API call as a quick fix.

I tried this and it didn't seem to solve the problem.

I borrowed some code from a blog which causes the rtb to flicker less while it's being updated:

        // Begin borrowed code from:
        // http://geekswithblogs.net/pvidler/archive/2003/10/15/182.aspx
        // All credits go to the above blog author :-) 

        [DllImport("user32", EntryPoint = "SendMessage")]
        private static extern int SendMessageB(IntPtr hWnd, uint msg, int wParam, ref POINT lp); 
        int updating = 0;
        IntPtr OldEventMask = IntPtr.Zero;
        const uint EM_GETSCROLLPOS = 0x0400 + 221;
        const uint EM_SETSCROLLPOS = 0x0400 + 222;
        struct POINT
        {
            public long X;
            public long Y;
        }
        POINT ScrollPosition = new POINT(); 
        public void BeginUpdate()
        {
            ++updating;
            if (updating > 1)
            {
                return;
            }
            SendMessageB(EditorBox.Handle, EM_GETSCROLLPOS, 0, ref ScrollPosition); 
            OldEventMask = SendMessage(EditorBox.Handle, EM_SETEVENTMASK, IntPtr.Zero, IntPtr.Zero);
            SendMessage(EditorBox.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
        }
        public void EndUpdate()
        {
            --updating;
            if (updating > 0)
            {
                return;
            }
            SendMessageB(EditorBox.Handle, EM_SETSCROLLPOS, 0, ref ScrollPosition); 
            SendMessage(EditorBox.Handle, WM_SETREDRAW, new IntPtr(1), IntPtr.Zero);
            SendMessage(EditorBox.Handle, EM_SETEVENTMASK, IntPtr.Zero, OldEventMask);
        }

        // End borrowed code. 

The get/setscrollbarpos is my current "solution" to the problem as it very nearly works, it just doesn't seem to work when I try to scroll above the line with the caret when using the up arrow on the scrollbar. It works fine scrolling up using the scroll wheel or the scrollbar thumb, just not the up arrow. Even more frustratingly, scrolling down past the caret works using the down arror, the thumb and the scroll wheel.

I call BeginUpdate(), then do all of my select() highlighting, then call EndUpdate(). If I change the EM_GET/SETSCROLLPOS lines to LockWindowUpdate(EditorBox.Handle) and LockWindowUpdate(0) respectively, this causes the scrollbar to flicker wildy and I'm unable to use the scrollbar entirely.

Any other ideas? I really can't believe Microsoft didn't implement a way to select text without scrolling seeing as that's the only way you can apply formatting to text!

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.