123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Windows.Forms;
- using System.Runtime.InteropServices;
- using System.Drawing;
- using System.ComponentModel;
- namespace FastReport.Controls
- {
- /// <summary>
- /// Specifies how text in a <see cref="FRRichTextBox"/> is horizontally aligned.
- /// </summary>
- internal enum TextAlign
- {
- /// <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
- }
- #if !DEBUG
- [DesignTimeVisible(false)]
- #endif
- internal class FRRichTextBox : RichTextBox
- {
- #region Fields, Structures
- private bool editor = false;
- // Constants from the Platform SDK.
- private const int EM_GETPARAFORMAT = 1085;
- private const int EM_SETPARAFORMAT = 1095;
- private const int EM_SETCHARFORMAT = 1092;
- private const int EM_SETTYPOGRAPHYOPTIONS = 1226;
- private const int EM_FORMATRANGE = 1081;
- private const int EM_SETTARGETDEVICE = 1096;
- private const int TO_ADVANCEDTYPOGRAPHY = 1;
- private const int PFM_ALIGNMENT = 8;
- private const int SCF_SELECTION = 1;
- private const int CFM_BOLD = 1;
- private const int CFM_ITALIC = 2;
- private const int CFM_UNDERLINE = 4;
- private const uint CFM_SIZE = 0x80000000;
- private const uint CFM_FACE = 0x20000000;
- private const int GWL_EXSTYLE = -20;
- private const int WS_EX_TRANSPARENT = 0x20;
- [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;
- // PARAFORMAT2 from here onwards.
- 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;
- }
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
- 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;
- // CHARFORMAT2 from here onwards.
- public short wWeight;
- public short sSpacing;
- public int crBackColor;
- #pragma warning disable FR0005 // Field must be texted in lowerCamelCase.
- public int LCID;
- #pragma warning restore FR0005 // Field must be texted in lowerCamelCase.
- public uint dwReserved;
- public short sStyle;
- public short wKerning;
- public byte bUnderlineType;
- public byte bAnimation;
- public byte bRevAuthor;
- public byte bReserved1;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct STRUCT_CHARRANGE
- {
- public int cpMin;
- public int cpMax;
- }
- #pragma warning disable FR0006 // Field name of struct must be longer than 2 characters.
- [StructLayout(LayoutKind.Sequential)]
- private struct STRUCT_FORMATRANGE
- {
- public IntPtr hdc;
- public IntPtr hdcTarget;
- public STRUCT_RECT rc;
- public STRUCT_RECT rcPage;
- public STRUCT_CHARRANGE chrg;
- }
- #pragma warning restore FR0006 // Field name of struct must be longer than 2 characters.
- [StructLayout(LayoutKind.Sequential)]
- private struct STRUCT_RECT
- {
- public int left;
- public int top;
- public int right;
- public int bottom;
- }
- [DllImport("user32", CharSet = CharSet.Auto)]
- private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
- [DllImport("user32", CharSet = CharSet.Auto)]
- private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
- [DllImport("user32", CharSet = CharSet.Auto)]
- private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref PARAFORMAT fmt);
- [DllImport("user32", CharSet = CharSet.Auto)]
- private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref CHARFORMAT fmt);
- [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
- static extern IntPtr LoadLibrary(string lpFileName);
- #endregion
- #region Properties
- /// <summary>
- /// Gets or sets the alignment to apply to the current
- /// selection or insertion point.
- /// </summary>
- /// <remarks>
- /// Replaces the SelectionAlignment from <see cref="RichTextBox"/>.
- /// </remarks>
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public new TextAlign SelectionAlignment
- {
- get
- {
- PARAFORMAT fmt = new PARAFORMAT();
- fmt.cbSize = Marshal.SizeOf(fmt);
- // Get the alignment.
- SendMessage(Handle, EM_GETPARAFORMAT, SCF_SELECTION, ref fmt);
- // Default to Left align.
- if ((fmt.dwMask & PFM_ALIGNMENT) == 0)
- return TextAlign.Left;
- return (TextAlign)fmt.wAlignment;
- }
- set
- {
- PARAFORMAT fmt = new PARAFORMAT();
- fmt.cbSize = Marshal.SizeOf(fmt);
- fmt.dwMask = PFM_ALIGNMENT;
- fmt.wAlignment = (short)value;
- // Set the alignment.
- SendMessage(Handle, EM_SETPARAFORMAT, SCF_SELECTION, ref fmt);
- }
- }
- #endregion
- #region Private Methods
- /// <summary>
- /// Convert between screen pixels and twips (1/1440 inch, used by Win32 API calls)
- /// </summary>
- /// <param name="n">Value in screen pixels</param>
- /// <returns>Value in twips</returns>
- private int PixelsToTwips(float n)
- {
- return (int)(n / 96 * 1440);
- }
- /// <summary>
- /// Convert between screen pixels and twips (1/1440 inch, used by Win32 API calls)
- /// </summary>
- /// <param name="twips">Value in twips</param>
- /// <returns>Value in screen pixels</returns>
- private float TwipsToPixels(int twips)
- {
- return twips / 1440f * 96f;
- }
- private void SetCharFormatMessage(ref CHARFORMAT fmt)
- {
- SendMessage(Handle, EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);
- }
- private void ApplyStyle(uint style, bool on)
- {
- CHARFORMAT fmt = new CHARFORMAT();
- fmt.cbSize = Marshal.SizeOf(fmt);
- fmt.dwMask = style;
- if (on)
- fmt.dwEffects = style;
- SetCharFormatMessage(ref fmt);
- }
- #endregion
- #region Protected Methods
- protected override CreateParams CreateParams
- {
- get
- {
- CreateParams prams = base.CreateParams;
- if (LoadLibrary("msftedit.dll") != IntPtr.Zero)
- {
- if(editor)
- prams.ExStyle |= WS_EX_TRANSPARENT; // transparent
- prams.ClassName = "RICHEDIT50W";
- }
- return prams;
- }
- }
- protected override void OnHandleCreated(EventArgs e)
- {
- base.OnHandleCreated(e);
- // Enable support for justification.
- SendMessage(Handle, EM_SETTYPOGRAPHYOPTIONS, TO_ADVANCEDTYPOGRAPHY, TO_ADVANCEDTYPOGRAPHY);
- }
- #endregion
- #region Public Methods
- /// <summary>
- /// Calculate or render the contents of RichTextBox for printing
- /// </summary>
- /// <param name="g">Graphics object</param>
- /// <param name="measureGraphics">Graphics object to measure richtext for</param>
- /// <param name="displayRect">Bonding rectangle of the RichTextBox</param>
- /// <param name="charFrom">Index of first character to be printed</param>
- /// <param name="charTo">Index of last character to be printed</param>
- /// <param name="measureOnly">If true, only the calculation is performed,
- /// otherwise the text is rendered as well</param>
- /// <returns>(Index of last character that fitted on the page) + 1</returns>
- public int FormatRange(Graphics g, Graphics measureGraphics, RectangleF displayRect,
- int charFrom, int charTo, bool measureOnly)
- {
- int i;
- return FormatRange(g, measureGraphics, displayRect, charFrom, charTo, measureOnly, out i);
- }
- /// <summary>
- /// Calculate or render the contents of RichTextBox for printing
- /// </summary>
- /// <param name="g">Graphics object</param>
- /// <param name="measureGraphics">Graphics object to measure richtext for</param>
- /// <param name="displayRect">Bonding rectangle of the RichTextBox</param>
- /// <param name="charFrom">Index of first character to be printed</param>
- /// <param name="charTo">Index of last character to be printed</param>
- /// <param name="measureOnly">If true, only the calculation is performed,
- /// otherwise the text is rendered as well</param>
- /// <param name="height">The calculated text height</param>
- /// <returns>(Index of last character that fitted on the page) + 1</returns>
- public int FormatRange(Graphics g, Graphics measureGraphics, RectangleF displayRect,
- int charFrom, int charTo, bool measureOnly, out int height)
- {
- // Specify which characters to print
- STRUCT_CHARRANGE cr;
- cr.cpMin = charFrom;
- cr.cpMax = charTo;
- // Specify the area inside page margins
- STRUCT_RECT rc;
- rc.left = PixelsToTwips(displayRect.Left);
- rc.top = PixelsToTwips(displayRect.Top);
- rc.right = PixelsToTwips(displayRect.Right);
- rc.bottom = PixelsToTwips(displayRect.Bottom);
- // Specify the page area
- STRUCT_RECT rcPage;
- rcPage.left = rc.left;
- rcPage.top = rc.top;
- rcPage.right = rc.right;
- rcPage.bottom = rc.bottom;
- // Get device context of output device
- IntPtr hdc = g.GetHdc();
- IntPtr measureHdc = g == measureGraphics ? hdc : measureGraphics.GetHdc();
- // Fill in the FORMATRANGE struct
- STRUCT_FORMATRANGE fr;
- fr.chrg = cr;
- fr.hdc = hdc;
- fr.hdcTarget = measureHdc;
- fr.rc = rc;
- fr.rcPage = rcPage;
- // Non-Zero wParam means render, Zero means measure
- int wParam = measureOnly ? 0 : 1;
- // Allocate memory for the FORMATRANGE struct and
- // copy the contents of our struct to this memory
- IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr));
- Marshal.StructureToPtr(fr, lParam, false);
- // Send the actual Win32 message
- int res = SendMessage(Handle, EM_FORMATRANGE, wParam, lParam);
- height = 0;
- if (measureOnly)
- {
- fr = (STRUCT_FORMATRANGE)Marshal.PtrToStructure(lParam, typeof(STRUCT_FORMATRANGE));
- height = (int)Math.Round(fr.rc.bottom / (1440f / 96f));
- }
- // Free allocated memory
- Marshal.FreeCoTaskMem(lParam);
- // and release the device context
- g.ReleaseHdc(hdc);
- if (g != measureGraphics)
- measureGraphics.ReleaseHdc(measureHdc);
- // finish the formatting
- SendMessage(Handle, EM_FORMATRANGE, 0, 0);
-
- return res;
- }
-
- public void SetSelectionFont(string face)
- {
- CHARFORMAT fmt = new CHARFORMAT();
- fmt.cbSize = Marshal.SizeOf(fmt);
- fmt.dwMask = CFM_FACE;
- fmt.szFaceName = new char[32];
- face.CopyTo(0, fmt.szFaceName, 0, Math.Min(face.Length, 31));
- SetCharFormatMessage(ref fmt);
- }
- public void SetSelectionSize(int size)
- {
- CHARFORMAT fmt = new CHARFORMAT();
- fmt.cbSize = Marshal.SizeOf(fmt);
- fmt.dwMask = CFM_SIZE;
- fmt.yHeight = size * 20;
- SetCharFormatMessage(ref fmt);
- }
- public void SetSelectionBold(bool value)
- {
- ApplyStyle(CFM_BOLD, value);
- }
- public void SetSelectionItalic(bool value)
- {
- ApplyStyle(CFM_ITALIC, value);
- }
- public void SetSelectionUnderline(bool value)
- {
- ApplyStyle(CFM_UNDERLINE, value);
- }
- public FRRichTextBox(bool editor) : base()
- {
- this.editor = editor;
- }
- public FRRichTextBox() : base() { }
- #endregion
- }
- /// <summary>
- /// Contener for better work FRRichTextBox
- /// </summary>
- #if !DEBUG
- [DesignTimeVisible(false)]
- #endif
- public class ContainerFRRichTextBox : Control
- {
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- protected override CreateParams CreateParams
- {
- get
- {
- CreateParams prams = base.CreateParams;
- prams.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
- return prams;
- }
- }
- }
- }
|