Fix for the RichTextBox Undo Information Lost When Retrieving Text
using System; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms;namespace TextUndoBuffer { /// <summary> /// Work around for KB 812943, The RichEdit Control Undo /// Information May Be Lost When the Control Retrieves Text. /// </summary> public class RichTextBoxEx : RichTextBox { [DllImport("user32.dll", EntryPoint="SendMessage", CharSet=CharSet.Auto )] static extern int SendMessage(IntPtr hWnd, int msg,
ref GETTEXTEX wParam, System.Text.StringBuilder lParam); [DllImport("user32.dll", EntryPoint="SendMessage", CharSet=CharSet.Auto )] static extern int SendMessage(IntPtr hWnd, int msg,ref GETTEXTLENGTHEX wParam, int lParam);[StructLayout(LayoutKind.Sequential)] </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> GETTEXTEX { </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Int32 cb; </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Int32 flags; </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Int32 codepage; </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> IntPtr lpDefaultChar; </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> IntPtr lpUsedDefChar; } [StructLayout(LayoutKind.Sequential)] </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> GETTEXTLENGTHEX { </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Int32 flags; </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Int32 codepage; } </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> WM_USER </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0x0400</span><span style="COLOR: #000000">; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> RichEdit messages (Richedit.h)</span><span style="COLOR: #008000">
const int EM_GETTEXTEX =(WM_USER + 94); const int EM_GETTEXTLENGTHEX =(WM_USER + 95); // Flags for the GETEXTEX data structure const int GT_DEFAULT = 0; // Flags for the GETTEXTLENGTHEX data structure const int GTL_DEFAULT = 0; // Do default (return # of chars) const int GTL_CLOSE = 4; // Fast computation of a "close" answer public RichTextBoxEx() { }
</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">override</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> Text { </span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000"> { GETTEXTLENGTHEX getLength </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> GETTEXTLENGTHEX(); getLength.flags </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> GTL_CLOSE; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">get buffer size</span><span style="COLOR: #008000">
getLength.codepage = 1200; //Unicode int textLength = SendMessage(base.Handle, EM_GETTEXTLENGTHEX, ref getLength, 0);
GETTEXTEX getText </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> GETTEXTEX(); getText.cb </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> textLength</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">add space for null terminator</span><span style="COLOR: #008000">
getText.flags = GT_DEFAULT; getText.codepage = 1200; //Unicode StringBuilder sb = new StringBuilder(getText.cb);
SendMessage(</span><span style="COLOR: #0000ff">base</span><span style="COLOR: #000000">.Handle, EM_GETTEXTEX, </span><span style="COLOR: #0000ff">ref</span><span style="COLOR: #000000"> getText, sb); </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> sb.ToString(); } </span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000"> { </span><span style="COLOR: #0000ff">base</span><span style="COLOR: #000000">.Text </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> value; } } </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">override</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> TextLength { </span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000"> { GETTEXTLENGTHEX getLength </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> GETTEXTLENGTHEX(); getLength.flags </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> GTL_DEFAULT; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Returns the number of characters</span><span style="COLOR: #008000">
getLength.codepage = 1200; //Unicode return SendMessage(base.Handle, EM_GETTEXTLENGTHEX, ref getLength, 0);
} } } }