In my work with the RichTextBox control, I've often run into this bug in the RichEdit control. You can read more about this bug by looking at Microsoft's knowledge base article -
812943. If you are unable to get the latest Riched20.dll then you can get around the problem using the following code …
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)]
struct GETTEXTEX
{
public Int32 cb;
public Int32 flags;
public Int32 codepage;
public IntPtr lpDefaultChar;
public IntPtr lpUsedDefChar;
}
[StructLayout(LayoutKind.Sequential)]
struct GETTEXTLENGTHEX
{
public Int32 flags;
public Int32 codepage;
}
const int WM_USER = 0x0400;
// RichEdit messages (Richedit.h)
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()
{
}
public override string Text
{
get
{
GETTEXTLENGTHEX getLength = new GETTEXTLENGTHEX();
getLength.flags = GTL_CLOSE; //get buffer size
getLength.codepage = 1200; //Unicode
int textLength = SendMessage(base.Handle,
EM_GETTEXTLENGTHEX,
ref getLength, 0);
GETTEXTEX getText = new GETTEXTEX();
getText.cb = textLength+2; //add space for null terminator
getText.flags = GT_DEFAULT;
getText.codepage = 1200; //Unicode
StringBuilder sb = new StringBuilder(getText.cb);
SendMessage(base.Handle,
EM_GETTEXTEX,
ref getText, sb);
return sb.ToString();
}
set
{
base.Text = value;
}
}
public override int TextLength
{
get
{
GETTEXTLENGTHEX getLength = new GETTEXTLENGTHEX();
getLength.flags = GTL_DEFAULT; //Returns the number of characters
getLength.codepage = 1200; //Unicode
return SendMessage(base.Handle,
EM_GETTEXTLENGTHEX,
ref getLength, 0);
}
}
}
}
~ Paul