using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace AMT_SW_GUI { //Parts of this file taken from codeproject public enum LineSpacingRule { Single, //single line Normal, // 1.5 line Double, // double line } public partial class AMT_RichTextbox : RichTextBox { private bool labelMode = true; public AMT_RichTextbox() { InitializeComponent(); this.TextChanged += new EventHandler(AMT_RichTextbox_TextChanged); } public AMT_RichTextbox(IContainer container) { container.Add(this); InitializeComponent(); this.TextChanged+=new EventHandler(AMT_RichTextbox_TextChanged); } [StructLayout(LayoutKind.Sequential)] private class PARAFORMAT2 { public int cbSize; public int 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 = 0x20)] public int[] rgxTabs; public int dySpaceBefore; // Vertical spacing before para public int dySpaceAfter; // Vertical spacing after para public int dyLineSpacing; // Line spacing depending on Rule public short sStyle; // Style handle public byte bLineSpacingRule; // Rule for line spacing (see tom.doc) public byte bOutlineLevel; // Outline Level public short wShadingWeight; // Shading in hundredths of a per cent public short wShadingStyle; // Byte 0: style, nib 2: cfpat, 3: cbpat public short wNumberingStart; // Starting value for numbering public short wNumberingStyle; // Alignment, Roman/Arabic, (), ), ., etc. public short wNumberingTab; // Space bet 1st indent and 1st-line text public short wBorderSpace; // Border-text spaces (nbl/bdr in pts) public short wBorderWidth; // Pen widths (nbl/bdr in half twips) public short wBorders; // Border styles (nibble/border) public PARAFORMAT2() { this.cbSize = Marshal.SizeOf(typeof(PARAFORMAT2)); } } #region PARAFORMAT MASK VALUES // PARAFORMAT mask values private const uint PFM_STARTINDENT = 0x00000001; private const uint PFM_RIGHTINDENT = 0x00000002; private const uint PFM_OFFSET = 0x00000004; private const uint PFM_ALIGNMENT = 0x00000008; private const uint PFM_TABSTOPS = 0x00000010; private const uint PFM_NUMBERING = 0x00000020; private const uint PFM_OFFSETINDENT = 0x80000000; // PARAFORMAT 2.0 masks and effects private const uint PFM_SPACEBEFORE = 0x00000040; private const uint PFM_SPACEAFTER = 0x00000080; private const uint PFM_LINESPACING = 0x00000100; private const uint PFM_STYLE = 0x00000400; private const uint PFM_BORDER = 0x00000800; // (*) private const uint PFM_SHADING = 0x00001000; // (*) private const uint PFM_NUMBERINGSTYLE = 0x00002000; // RE 3.0 private const uint PFM_NUMBERINGTAB = 0x00004000; // RE 3.0 private const uint PFM_NUMBERINGSTART = 0x00008000; // RE 3.0 private const uint PFM_RTLPARA = 0x00010000; private const uint PFM_KEEP = 0x00020000; // (*) private const uint PFM_KEEPNEXT = 0x00040000; // (*) private const uint PFM_PAGEBREAKBEFORE = 0x00080000; // (*) private const uint PFM_NOLINENUMBER = 0x00100000; // (*) private const uint PFM_NOWIDOWCONTROL = 0x00200000; // (*) private const uint PFM_DONOTHYPHEN = 0x00400000; // (*) private const uint PFM_SIDEBYSIDE = 0x00800000; // (*) private const uint PFM_TABLE = 0x40000000; // RE 3.0 private const uint PFM_TEXTWRAPPINGBREAK = 0x20000000; // RE 3.0 private const uint PFM_TABLEROWDELIMITER = 0x10000000; // RE 4.0 // The following three properties are read only private const uint PFM_COLLAPSED = 0x01000000; // RE 3.0 private const uint PFM_OUTLINELEVEL = 0x02000000; // RE 3.0 private const uint PFM_BOX = 0x04000000; // RE 3.0 private const uint PFM_RESERVED2 = 0x08000000; // RE 4.0 #endregion [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] PARAFORMAT2 lParam); #region AutoSize private bool autoSize = false; public void SetAutoSize(bool turnOn) { autoSize = turnOn; } #endregion #region Line Spacing public void SetLineSpacingRule(byte rule) { PARAFORMAT2 pf = new PARAFORMAT2(); pf.dwMask = (int)(PFM_LINESPACING); pf.bLineSpacingRule = rule; SendMessage(new System.Runtime.InteropServices.HandleRef(this, this.Handle), 0x447, 0, pf); } private double lineSpacingRule = 0; private LineSpacingRule lineSpacing = LineSpacingRule.Single; public LineSpacingRule LineSpacing { get { return lineSpacing; } set { lineSpacing = value; switch (value) { case LineSpacingRule.Single: { lineSpacingRule = 1; SetLineSpacingRule(0); break; } case LineSpacingRule.Normal: { lineSpacingRule = 1.5; SetLineSpacingRule(1); break; } case LineSpacingRule.Double: { lineSpacingRule = 2; SetLineSpacingRule(2); break; } } } } #endregion protected override void WndProc(ref Message m) { const int WM_SETFOCUS = 0x0007; if (labelMode == true) { //this code prevents from the user to edit/get focus the rich text box if (m.Msg == WM_SETFOCUS) { m.Result = IntPtr.Zero; } else base.WndProc(ref m); } else { base.WndProc(ref m); } } public bool LabelMode { get { return labelMode; } set { labelMode = value; if (labelMode == true) { // for label mode , the control is readonly this.ReadOnly = true; } } } void AMT_RichTextbox_TextChanged(object sender, EventArgs e) { if (autoSize == true) { LineSpacing = lineSpacing; this.Height = Convert.ToInt32((((this.GetLineFromCharIndex(this.Text.Length) + 1) * this.Font.Height + 1 + this.Margin.Vertical) * lineSpacingRule)) + 2; this.SelectionStart = 0; } this.SelectionStart = this.Text.Length; this.ScrollToCaret(); } } }