8

I have a richTextBox I am using to perform some syntax highlighting. This is a small editing facility so I have not written a custom syntax highlighter - instead I am using Regexs and updating upon the detection of an input delay using an event handler for the Application.Idle event:

Application.Idle += new EventHandler(Application_Idle);

in the event handler I check for the time the text box has been inactive:

private void Application_Idle(object sender, EventArgs e)
{
    // Get time since last syntax update.
    double timeRtb1 = DateTime.Now.Subtract(_lastChangeRtb1).TotalMilliseconds;

   // If required highlight syntax.
   if (timeRtb1 > MINIMUM_UPDATE_DELAY)
   {
       HighlightSyntax(ref richTextBox1);
       _lastChangeRtb1 = DateTime.MaxValue;
   }
}

But even for relatively small highlights the RichTextBox flickers heavily and it has no richTextBox.BeginUpdate()/EndUpdate() methods. To overcome this I found this answer to a similar dilemma by Hans Passant (Hans Passant has never let me down!):

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

class MyRichTextBox : RichTextBox 
{ 
    public void BeginUpdate() 
    { 
        SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero); 
    }

    public void EndUpdate() 
    { 
        SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);  
    } 

    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
    private const int WM_SETREDRAW = 0x0b; 
} 

However, this gives me odd behaviour upon an update; the cursor dies/freezes and shows nothing but odd looking stripes (see image below).

Odd Error Caused by RichTextBox Method Extension

I clearly can't use an alternative thread to update the UI, so what am I doing wrong here?

Thanks for your time.

Community
  • 1
  • 1
MoonKnight
  • 23,214
  • 40
  • 145
  • 277

1 Answers1

10

Try modifying the EndUpdate to also call Invalidate afterwards. The control doesn't know it needs to do some updating, so you need to tell it:

public void EndUpdate() 
{ 
  SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);  
  this.Invalidate();
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • That is mint! Worked like a charm... One small question, how do you learn about Extension Methods and their subtleties? `SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);` is not exactly standard C#!? Or is it? – MoonKnight Feb 23 '12 at 19:42
  • 1
    @Killercam `SendMessage` and Extensions are two different things. `SendMessage` is calling a windows API function. For Extensions, see [Extension Methods (C# Programming Guide)](http://msdn.microsoft.com/en-us/library/bb383977.aspx). – LarsTech Feb 23 '12 at 19:54
  • Thanks for your reply. I realise that the two are different. Thanks for the link and your help, it is most appreciated. – MoonKnight Feb 23 '12 at 20:51