Answered Increase RichTextBox Undo/Redo Limit

  • Monday, April 30, 2012 8:45 PM
     
     

    Hello everyone,

    I was wondering if there is a way to modify the limit on the number of undo/redo actions a RichTextBox is capable of performing. It seems as though the limit is around 100, and I really need to increase this because of the demands of my application. I have text formatting (Bold, Underline, etc.) in my application, and since you can change the font of the text, I need to loop through the characters in the SelectedText one-by-one and apply the correct formatting to them in order to prevent any errors from appearing. Every time a single character is formatted, it counts as an action. As you can imagine, this quickly adds up and therefore makes my undo/redo features not as useful as I'd hope with the 100-action limit.

    Does anyone have any suggestions for me? Thanks in advance for any assistance!

All Replies

  • Monday, April 30, 2012 9:05 PM
    Moderator
     
     Answered

    No, I think you've hit the limits of simple RichTextBox usage.  I think you'd have to switch to having your code do all of the modifications on the RtfText directly so that you can apply multiple formatting changes simultaneously. But then you'd have to work with the rich text markup directly instead of using the methods on the control.

    Keep in mind that the RichTextBox isn't really suitable for formatting any more complex than that of WordPad, where formatting applies to the selection, with existing formatting being overriden.  Per-character formatting is probably beyond the capabilities of the RichTextBox.  You'll probably want to use a third party .Net control (usually cost $), try to make Scintilla work (can be a pain in VB.Net), or write your own custom control from the ground up (no small undertaking).

    Your best bet may just be to reduce the intended functionality (I know that answer stinks... sorry).


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


  • Tuesday, May 01, 2012 2:54 PM
     
     

    No, I think you've hit the limits of simple RichTextBox usage.  I think you'd have to switch to having your code do all of the modifications on the RtfText directly so that you can apply multiple formatting changes simultaneously. But then you'd have to work with the rich text markup directly instead of using the methods on the control.

    Keep in mind that the RichTextBox isn't really suitable for formatting any more complex than that of WordPad, where formatting applies to the selection, with existing formatting being overriden.  Per-character formatting is probably beyond the capabilities of the RichTextBox.  You'll probably want to use a third party .Net control (usually cost $), try to make Scintilla work (can be a pain in VB.Net), or write your own custom control from the ground up (no small undertaking).

    Your best bet may just be to reduce the intended functionality (I know that answer stinks... sorry).


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


    Hello Reed,

    Thank you for the answer! I will have to think about how I am going to go about resolving this issue, and I will definitely keep your suggestions in mind. Thanks again for the help!

  • Tuesday, May 01, 2012 11:56 PM
     
     

    I could be wrong here, but I believe this is one of the rare occasions where Reed has given an incorrect response.

    You can send the Rich Edit Control the EM_SETUNDOLIMIT message to change this (http://msdn.microsoft.com/en-us/library/windows/desktop/bb774290%28v=vs.85%29.aspx).  I would recommend that you derive your own extended RTB similar to the code that follows as it makes it easier to send messages to the control using the WndProc or you could PInvoke SendMessage to send the needed message to the RTB window handle.

    Public Class Form1


       Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
          'this works on my system.  Did not verify that I could do 500 undo's
          ExRTB1.UndoLimit = 500
          MsgBox(ExRTB1.UndoLimit.ToString)
       End Sub

       Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
          'This failed and left the UndoLimit value unchanged
          ExRTB1.UndoLimit = Int32.MaxValue
          MsgBox(ExRTB1.UndoLimit.ToString)
       End Sub
    End Class

    Public Class ExRTB
       Inherits RichTextBox

       Private Const WM_User As Int32 = &H400
       Private Const EM_SetUndoLimit As Int32 = WM_User + 82



       Private _UndoLimit As Int32 = 100 ' The default value
       Public Property UndoLimit() As Int32
          Get
             Dim m As New System.Windows.Forms.Message With {.HWnd = Me.Handle, _
                                                             .Msg = EM_SetUndoLimit, _
                                                             .WParam = New IntPtr(_UndoLimit), _
                                                             .LParam = IntPtr.Zero}
             WndProc(m)
             Return m.Result.ToInt32
          End Get
          Set(ByVal value As Int32)
             Dim m As New System.Windows.Forms.Message With {.HWnd = Me.Handle, _
                                                             .Msg = EM_SetUndoLimit, _
                                                             .WParam = New IntPtr(value), _
                                                             .LParam = IntPtr.Zero}
             WndProc(m)
             If m.Result.ToInt32 <> value Then
                Throw New ArgumentException("Error setting undolimit.  Limit currently at " & m.Result.ToString)
                _UndoLimit = m.Result.ToInt32
             Else
                _UndoLimit = value
             End If
          End Set
       End Property 'UndoLimit


    End Class