Sorry for that..Probably my reply was not clear anyways here is the sample code.. Let me know if this works for you
/* ========================== */
/* ========================== */
/* ========================== */
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace FlatControls2
{
/// <summary>
/// Represents a custom rich text box control with additional properties for internal use.
/// </summary>
public class CustomRichTextBox : RichTextBox
{
#region Private fields and constructors
private int _Updating = 0;
private int _OldEventMask = 0;
/// <summary>
/// Initializes a new instance of the <see cref="CustomRichTextBox"/> class.
/// </summary>
public CustomRichTextBox()
{
/*
* The following list describes which versions of Rich Edit are included in which releases of Microsoft Windows?.
*
* Windows XP SP1 Includes Rich Edit 4.1, Rich Edit 3.0, and a Rich Edit 1.0 emulator.
* Windows XP Includes Rich Edit 3.0 with a Rich Edit 1.0 emulator.
* Windows Me Includes Rich Edit 1.0 and 3.0.
* Windows 2000 Includes Rich Edit 3.0 with a Rich Edit 1.0 emulator.
* Windows NT 4.0 Includes Rich Edit 1.0 and 2.0.
* Windows 98 Includes Rich Edit 1.0 and 2.0.
* Windows 95 Includes only Rich Edit 1.0. However, Riched20.dll is compatible with Windows 95 and may be installed by an application that requires it.
*/
// Remove any XP style applied to the rich text box.
RemoveTheme();
}
#endregion
#region Windows API
private const int WM_SETREDRAW = 0x0B;
private const int EM_SETEVENTMASK = 0x0431;
private const int EM_SETCHARFORMAT = 0x0444;
private const int EM_GETCHARFORMAT = 0x043A;
private const int EM_GETPARAFORMAT = 0x043D;
private const int EM_SETPARAFORMAT = 0x0447;
private const int EM_SETTYPOGRAPHYOPTIONS = 0x04CA;
private const int CFM_UNDERLINETYPE = 0x800000;
private const int CFM_BACKCOLOR = 0x4000000;
private const int CFE_AUTOBACKCOLOR = 0x4000000;
private const int SCF_SELECTION = 0x01;
private const int PFM_ALIGNMENT = 0x08;
private const int TO_ADVANCEDTYPOGRAPHY = 0x01;
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern int SendMessage(HandleRef hWnd, int msg, int wParam, int lParam);
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern int SendMessage(HandleRef hWnd, int msg, int wParam, ref CHARFORMAT2 lParam);
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern int SendMessage(HandleRef hWnd, int msg, int wParam, ref PARAFORMAT2 lParam);
[DllImport("uxtheme.dll", CharSet=CharSet.Unicode)]
private static extern int SetWindowTheme(
HandleRef hWnd,
[MarshalAs(UnmanagedType.LPWStr)]
string pszSubAppName,
[MarshalAs(UnmanagedType.LPWStr)]
string pszSubIdList);
/// <summary>
/// Contains information about character formatting in a rich edit control.
/// </summary>
/// <remarks><see cref="CHARFORMAT"/> works with all Rich Edit versions.</remarks>
[StructLayout(LayoutKind.Sequential)]
private struct CHARFORMAT
{
public int cbSize;
public uint dwMask;
public uint dwEffects;
public int yHeight;
public int yOffset;
public int crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
public char[] szFaceName;
}
/// <summary>
/// Contains information about character formatting in a rich edit control.
/// </summary>
/// <remarks><see cref="CHARFORMAT2"/> requires Rich Edit 2.0.</remarks>
[StructLayout(LayoutKind.Sequential)]
private struct CHARFORMAT2
{
public int cbSize;
public uint dwMask;
public uint dwEffects;
public int yHeight;
public int yOffset;
public int crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
public char[] szFaceName;
public short wWeight;
public short sSpacing;
public int crBackColor;
public int LCID;
public uint dwReserved;
public short sStyle;
public short wKerning;
public byte bUnderlineType;
public byte bAnimation;
public byte bRevAuthor;
}
/// <summary>
/// Contains information about paragraph formatting in a rich edit control.
/// </summary>
/// <remarks><see cref="PARAFORMAT"/> works with all Rich Edit versions.</remarks>
[StructLayout(LayoutKind.Sequential)]
private struct PARAFORMAT
{
public int cbSize;
public uint dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public int[] rgxTabs;
}
/// <summary>
/// Contains information about paragraph formatting in a rich edit control.
/// </summary>
/// <remarks><see cref="PARAFORMAT2"/> requires Rich Edit 2.0.</remarks>
[StructLayout(LayoutKind.Sequential)]
private struct PARAFORMAT2
{
public int cbSize;
public uint dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public int[] rgxTabs;
public int dySpaceBefore;
public int dySpaceAfter;
public int dyLineSpacing;
public short sStyle;
public byte bLineSpacingRule;
public byte bOutlineLevel;
public short wShadingWeight;
public short wShadingStyle;
public short wNumberingStart;
public short wNumberingStyle;
public short wNumberingTab;
public short wBorderSpace;
public short wBorderWidth;
public short wBorders;
}
#endregion
#region Property: SelectionUnderlineStyle
/// <summary>
/// Gets or sets the underline style to apply to the current selection or insertion point.
/// </summary>
/// <value>A <see cref="UnderlineStyle"/> that represents the underline style to
/// apply to the current text selection or to text entered after the insertion point.</value>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public UnderlineStyle SelectionUnderlineStyle
{
get
{
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
// Get the underline style
SendMessage(new HandleRef(this, Handle), EM_GETCHARFORMAT, SCF_SELECTION, ref fmt);
if ((fmt.dwMask & CFM_UNDERLINETYPE) == 0)
{
return UnderlineStyle.None;
}
else
{
byte style = (byte)(fmt.bUnderlineType & 0x0F);
return (UnderlineStyle)style;
}
}
set
{
// Ensure we don't alter the color
UnderlineColor color = SelectionUnderlineColor;
// Ensure we don't show it if it shouldn't be shown
if (value == UnderlineStyle.None)
color = UnderlineColor.Black;
// Set the underline type
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = CFM_UNDERLINETYPE;
fmt.bUnderlineType = (byte)((byte)value | (byte)color);
SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);
}
}
#endregion
#region Property: SelectionUnderlineColor
/// <summary>
/// Gets or sets the underline color to apply to the current selection or insertion point.
/// </summary>
/// <value>A <see cref="UnderlineColor"/> that represents the underline color to
/// apply to the current text selection or to text entered after the insertion point.</value>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public UnderlineColor SelectionUnderlineColor
{
get
{
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
// Get the underline color
SendMessage(new HandleRef(this, Handle), EM_GETCHARFORMAT, SCF_SELECTION, ref fmt);
if ((fmt.dwMask & CFM_UNDERLINETYPE) == 0)
{
return UnderlineColor.None;
}
else
{
byte style = (byte)(fmt.bUnderlineType & 0xF0);
return (UnderlineColor)style;
}
}
set
{
// If the an underline color of "None" is specified, remove underline effect
if (value == UnderlineColor.None)
{
SelectionUnderlineStyle = UnderlineStyle.None;
}
else
{
// Ensure we don't alter the style
UnderlineStyle style = SelectionUnderlineStyle;
// Ensure we don't show it if it shouldn't be shown
if (style == UnderlineStyle.None)
value = UnderlineColor.Black;
// Set the underline color
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = CFM_UNDERLINETYPE;
fmt.bUnderlineType = (byte)((byte)style | (byte)value);
SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);
}
}
}
#endregion
#region Property: SelectionBackColor
/// <summary>
/// Gets or sets the background color to apply to the
/// current selection or insertion point.
/// </summary>
/// <value>A <see cref="Color"/> that represents the background color to
/// apply to the current text selection or to text entered after the insertion point.</value>
/// <remarks>
/// <para>A value of Color.Empty indicates that the default background color is used.</para>
/// <para>If the selection contains more than one background
/// color, then this property will indicate it by
/// returning Color.Empty.</para>
/// </remarks>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Color SelectionBackColor
{
get
{
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
// Get the background color
SendMessage(new HandleRef(this, Handle), EM_GETCHARFORMAT, SCF_SELECTION, ref fmt);
// Default to Color.Empty as there could be
// several colors present in this selection
if ((fmt.dwMask & CFM_BACKCOLOR) == 0)
return Color.Empty;
// Default to Color.Empty if the background color is automatic
if ((fmt.dwEffects & CFE_AUTOBACKCOLOR) == CFE_AUTOBACKCOLOR)
return Color.Empty;
// Deal with the weird Windows color format
return ColorTranslator.FromWin32(fmt.crBackColor);
}
set
{
CHARFORMAT2 fmt = new CHARFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = CFM_BACKCOLOR;
if (value.IsEmpty)
fmt.dwEffects = CFE_AUTOBACKCOLOR;
else
fmt.crBackColor = ColorTranslator.ToWin32(value);
// Set the background color
SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);
}
}
#endregion
#region Property: SelectionAlignment
/// <summary>
/// Gets or sets the text alignment to apply to the current
/// selection or insertion point.
/// </summary>
/// <value>A member of the <see cref="RichTextAlign"/> enumeration that represents
/// the text alignment to apply to the current text selection or to text entered
/// after the insertion point.</value>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new RichTextAlign SelectionAlignment
{
get
{
PARAFORMAT2 fmt = new PARAFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
SendMessage(new HandleRef(this, Handle), EM_GETPARAFORMAT, SCF_SELECTION, ref fmt);
if ((fmt.dwMask & PFM_ALIGNMENT) == 0)
return RichTextAlign.Unknown;
else
return (RichTextAlign)fmt.wAlignment;
}
set
{
PARAFORMAT2 fmt = new PARAFORMAT2();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = PFM_ALIGNMENT;
fmt.wAlignment = (short)value;
// Set the alignment
SendMessage(new HandleRef(this, Handle), EM_SETPARAFORMAT, SCF_SELECTION, ref fmt);
}
}
#endregion
#region Method: BeginUpdate
/// <summary>
/// Maintains performance while updating.
/// </summary>
/// <remarks>
/// <para>
/// It is recommended to call this method before doing
/// any major updates that you do not wish the user to
/// see. Remember to call EndUpdate when you are finished
/// with the update. Nested calls are supported.
/// </para>
/// <para>
/// Calling this method will prevent redrawing. It will
/// also setup the event mask of the underlying richedit
/// control so that no events are sent.
/// </para>
/// </remarks>
public void BeginUpdate()
{
// Deal with nested calls
_Updating++;
if (_Updating > 1)
return;
// Prevent the control from raising any events
_OldEventMask = SendMessage(new HandleRef(this, Handle), EM_SETEVENTMASK, 0, 0);
// Prevent the control from redrawing itself
SendMessage(new HandleRef(this, Handle),WM_SETREDRAW, 0, 0);
}
#endregion
#region Method: EndUpdate
/// <summary>
/// Resumes drawing and event handling.
/// </summary>
/// <remarks>
/// This method should be called every time a call is made
/// made to BeginUpdate. It resets the event mask to it's
/// original value and enables redrawing of the control.
/// </remarks>
public void EndUpdate()
{
// Deal with nested calls
_Updating--;
if (_Updating > 0)
return;
// Allow the control to redraw itself
SendMessage(new HandleRef(this, Handle), WM_SETREDRAW, 1, 0);
// Allow the control to raise event messages
SendMessage(new HandleRef(this, Handle), EM_SETEVENTMASK, 0, _OldEventMask);
}
#endregion
#region Method: RemoveTheme
/// <summary>
/// Removes the themed style from the specified window.
/// </summary>
/// <param name="handle">An <see cref="IntPtr"/> that contains the window handle (HWND) of the control.</param>
private void RemoveTheme()
{
// Check OS version
bool supportsThemes = false;
if (System.Environment.OSVersion.Version.Major > 5)
supportsThemes = true;
else if ((System.Environment.OSVersion.Version.Major == 5) && (System.Environment.OSVersion.Version.Minor >= 1))
supportsThemes = true;
// Call API function
if (supportsThemes)
SetWindowTheme(new HandleRef(this, Handle), " ", " ");
}
#endregion
#region Method: OnHandleCreated
/// <summary>
/// Raises the <see cref="HandleCreated"/> event.
/// </summary>
/// <param name="e">An <see cref="EventArgs"/> that contains the event data.</param>
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
// Enable support for justification
SendMessage(new HandleRef(this, Handle), EM_SETTYPOGRAPHYOPTIONS, TO_ADVANCEDTYPOGRAPHY, TO_ADVANCEDTYPOGRAPHY);
}
#endregion
}
/// <summary>
/// Specifies horizontal alignment for a segment of rich text.
/// </summary>
public enum RichTextAlign
{
/// <summary>
/// The text alignment is unknown.
/// </summary>
Unknown = 0,
/// <summary>
/// The text is aligned to the left.
/// </summary>
Left = 1,
/// <summary>
/// The text is aligned to the right.
/// </summary>
Right = 2,
/// <summary>
/// The text is aligned in the center.
/// </summary>
Center = 3,
/// <summary>
/// The text is justified.
/// </summary>
Justify = 4
}
/// <summary>
/// Specifies the underline styles for a segment of rich text.
/// </summary>
public enum UnderlineStyle
{
/// <summary>
/// No underlining.
/// </summary>
None = 0,
/// <summary>
/// Single-line solid underline.
/// </summary>
Normal = 1,
/// <summary>
/// Single-line underline broken between words.
/// </summary>
Word = 2,
/// <summary>
/// Double-line underline.
/// </summary>
Double = 3,
/// <summary>
/// 'Dotted' pattern underline.
/// </summary>
Dotted = 4,
/// <summary>
/// 'Dash' pattern underline.
/// </summary>
Dash = 5,
/// <summary>
/// 'Dash-dot' pattern underline.
/// </summary>
DashDot = 6,
/// <summary>
/// 'Dash-dot-dot' pattern underline.
/// </summary>
DashDotDot = 7,
/// <summary>
/// Single-line wave style underline.
/// </summary>
Wave = 8,
/// <summary>
/// Single-line solid underline with extra thickness.
/// </summary>
Thick = 9,
/// <summary>
/// Single-line solid underline with less thickness.
/// </summary>
HairLine = 10,
/// <summary>
/// Double-line wave style underline.
/// </summary>
DoubleWave = 11,
/// <summary>
/// Single-line wave style underline with extra thickness.
/// </summary>
HeavyWave = 12,
/// <summary>
/// 'Long Dash' pattern underline.
/// </summary>
LongDash = 13,
/// <summary>
/// 'Dash' pattern underline with extra thickness.
/// </summary>
ThickDash = 14,
/// <summary>
/// 'Dash-dot' pattern underline with extra thickness.
/// </summary>
ThickDashDot = 15,
/// <summary>
/// 'Dash-dot-dot' pattern underline with extra thickness.
/// </summary>
ThickDashDotDot = 16,
/// <summary>
/// 'Dotted' pattern underline with extra thickness.
/// </summary>
ThickDotted = 17,
/// <summary>
/// 'Long Dash' pattern underline with extra thickness.
/// </summary>
ThickLongDash = 18
}
/// <summary>
/// Specifies the color of underline for a segment of rich text.
/// </summary>
public enum UnderlineColor
{
/// <summary>
/// No specific underline color specified.
/// </summary>
None = -1,
/// <summary>
/// Black.
/// </summary>
Black = 0x00,
/// <summary>
/// Blue.
/// </summary>
Blue = 0x10,
/// <summary>
/// Cyan.
/// </summary>
Cyan = 0x20,
/// <summary>
/// LimeGreen.
/// </summary>
LimeGreen = 0x30,
/// <summary>
/// Magenta.
/// </summary>
Magenta = 0x40,
/// <summary>
/// Red.
/// </summary>
Red = 0x50,
/// <summary>
/// Yellow.
/// </summary>
Yellow = 0x60,
/// <summary>
/// White.
/// </summary>
White = 0x70,
/// <summary>
/// DarkBlue.
/// </summary>
DarkBlue = 0x80,
/// <summary>
/// DarkCyan.
/// </summary>
DarkCyan = 0x90,
/// <summary>
/// Green.
/// </summary>
Green = 0xA0,
/// <summary>
/// DarkMagenta.
/// </summary>
DarkMagenta = 0xB0,
/// <summary>
/// Brown.
/// </summary>
Brown = 0xC0,
/// <summary>
/// OliveGreen.
/// </summary>
OliveGreen = 0xD0,
/// <summary>
/// DarkGray.
/// </summary>
DarkGray = 0xE0,
/// <summary>
/// Gray.
/// </summary>
Gray = 0xF0
}
}