1639 lines
62 KiB
C#
1639 lines
62 KiB
C#
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.ComponentModel;
|
|||
|
using System.Data;
|
|||
|
using System.Drawing;
|
|||
|
using System.Linq;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Text;
|
|||
|
using System.Windows.Forms;
|
|||
|
|
|||
|
namespace Payroll.Controls
|
|||
|
{
|
|||
|
public partial class HtmlRichTextBox : RichTextBox
|
|||
|
{
|
|||
|
public HtmlRichTextBox()
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private int updating = 0;
|
|||
|
private int oldEventMask = 0;
|
|||
|
|
|||
|
/// <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);
|
|||
|
}
|
|||
|
|
|||
|
/// <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);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns true when the control is performing some
|
|||
|
/// internal updates, specially when is reading or writing
|
|||
|
/// HTML text
|
|||
|
/// </summary>
|
|||
|
public bool InternalUpdating
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return (updating != 0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#region Win32 Apis
|
|||
|
|
|||
|
// Constants from the Platform SDK.
|
|||
|
private const int EM_FORMATRANGE = 1081;
|
|||
|
|
|||
|
private const int WM_USER = 0x0400;
|
|||
|
private const int EM_GETCHARFORMAT = WM_USER + 58;
|
|||
|
private const int EM_SETCHARFORMAT = WM_USER + 68;
|
|||
|
|
|||
|
private const int EM_SETEVENTMASK = 1073;
|
|||
|
private const int EM_GETPARAFORMAT = 1085;
|
|||
|
private const int EM_SETPARAFORMAT = 1095;
|
|||
|
private const int EM_SETTYPOGRAPHYOPTIONS = 1226;
|
|||
|
private const int WM_SETREDRAW = 11;
|
|||
|
private const int TO_ADVANCEDTYPOGRAPHY = 1;
|
|||
|
|
|||
|
|
|||
|
// Defines for EM_SETCHARFORMAT/EM_GETCHARFORMAT
|
|||
|
private const Int32 SCF_SELECTION = 0x0001;
|
|||
|
private const Int32 SCF_WORD = 0x0002;
|
|||
|
private const Int32 SCF_ALL = 0x0004;
|
|||
|
|
|||
|
public const int LF_FACESIZE = 32;
|
|||
|
|
|||
|
// Defines for STRUCT_CHARFORMAT member dwMask
|
|||
|
public const UInt32 CFM_BOLD = 0x00000001;
|
|||
|
public const UInt32 CFM_ITALIC = 0x00000002;
|
|||
|
public const UInt32 CFM_UNDERLINE = 0x00000004;
|
|||
|
public const UInt32 CFM_STRIKEOUT = 0x00000008;
|
|||
|
public const UInt32 CFM_PROTECTED = 0x00000010;
|
|||
|
public const UInt32 CFM_LINK = 0x00000020;
|
|||
|
public const UInt32 CFM_SIZE = 0x80000000;
|
|||
|
public const UInt32 CFM_COLOR = 0x40000000;
|
|||
|
public const UInt32 CFM_FACE = 0x20000000;
|
|||
|
public const UInt32 CFM_OFFSET = 0x10000000;
|
|||
|
public const UInt32 CFM_CHARSET = 0x08000000;
|
|||
|
public const UInt32 CFM_SUBSCRIPT = CFE_SUBSCRIPT | CFE_SUPERSCRIPT;
|
|||
|
public const UInt32 CFM_SUPERSCRIPT = CFM_SUBSCRIPT;
|
|||
|
|
|||
|
// Defines for STRUCT_CHARFORMAT member dwEffects
|
|||
|
public const UInt32 CFE_BOLD = 0x00000001;
|
|||
|
public const UInt32 CFE_ITALIC = 0x00000002;
|
|||
|
public const UInt32 CFE_UNDERLINE = 0x00000004;
|
|||
|
public const UInt32 CFE_STRIKEOUT = 0x00000008;
|
|||
|
public const UInt32 CFE_PROTECTED = 0x00000010;
|
|||
|
public const UInt32 CFE_LINK = 0x00000020;
|
|||
|
public const UInt32 CFE_AUTOCOLOR = 0x40000000;
|
|||
|
public const UInt32 CFE_SUBSCRIPT = 0x00010000; /* Superscript and subscript are */
|
|||
|
public const UInt32 CFE_SUPERSCRIPT = 0x00020000; /* mutually exclusive */
|
|||
|
|
|||
|
public const byte CFU_UNDERLINENONE = 0x00;
|
|||
|
public const byte CFU_UNDERLINE = 0x01;
|
|||
|
public const byte CFU_UNDERLINEWORD = 0x02; /* (*) displayed as ordinary underline */
|
|||
|
public const byte CFU_UNDERLINEDOUBLE = 0x03; /* (*) displayed as ordinary underline */
|
|||
|
public const byte CFU_UNDERLINEDOTTED = 0x04;
|
|||
|
public const byte CFU_UNDERLINEDASH = 0x05;
|
|||
|
public const byte CFU_UNDERLINEDASHDOT = 0x06;
|
|||
|
public const byte CFU_UNDERLINEDASHDOTDOT = 0x07;
|
|||
|
public const byte CFU_UNDERLINEWAVE = 0x08;
|
|||
|
public const byte CFU_UNDERLINETHICK = 0x09;
|
|||
|
public const byte CFU_UNDERLINEHAIRLINE = 0x0A; /* (*) displayed as ordinary underline */
|
|||
|
|
|||
|
public const int CFM_SMALLCAPS = 0x0040; /* (*) */
|
|||
|
public const int CFM_ALLCAPS = 0x0080; /* Displayed by 3.0 */
|
|||
|
public const int CFM_HIDDEN = 0x0100; /* Hidden by 3.0 */
|
|||
|
public const int CFM_OUTLINE = 0x0200; /* (*) */
|
|||
|
public const int CFM_SHADOW = 0x0400; /* (*) */
|
|||
|
public const int CFM_EMBOSS = 0x0800; /* (*) */
|
|||
|
public const int CFM_IMPRINT = 0x1000; /* (*) */
|
|||
|
public const int CFM_DISABLED = 0x2000;
|
|||
|
public const int CFM_REVISED = 0x4000;
|
|||
|
|
|||
|
public const int CFM_BACKCOLOR = 0x04000000;
|
|||
|
public const int CFM_LCID = 0x02000000;
|
|||
|
public const int CFM_UNDERLINETYPE = 0x00800000; /* Many displayed by 3.0 */
|
|||
|
public const int CFM_WEIGHT = 0x00400000;
|
|||
|
public const int CFM_SPACING = 0x00200000; /* Displayed by 3.0 */
|
|||
|
public const int CFM_KERNING = 0x00100000; /* (*) */
|
|||
|
public const int CFM_STYLE = 0x00080000; /* (*) */
|
|||
|
public const int CFM_ANIMATION = 0x00040000; /* (*) */
|
|||
|
public const int CFM_REVAUTHOR = 0x00008000;
|
|||
|
|
|||
|
// Font Weights
|
|||
|
public const short FW_DONTCARE = 0;
|
|||
|
public const short FW_THIN = 100;
|
|||
|
public const short FW_EXTRALIGHT = 200;
|
|||
|
public const short FW_LIGHT = 300;
|
|||
|
public const short FW_NORMAL = 400;
|
|||
|
public const short FW_MEDIUM = 500;
|
|||
|
public const short FW_SEMIBOLD = 600;
|
|||
|
public const short FW_BOLD = 700;
|
|||
|
public const short FW_EXTRABOLD = 800;
|
|||
|
public const short FW_HEAVY = 900;
|
|||
|
|
|||
|
public const short FW_ULTRALIGHT = FW_EXTRALIGHT;
|
|||
|
public const short FW_REGULAR = FW_NORMAL;
|
|||
|
public const short FW_DEMIBOLD = FW_SEMIBOLD;
|
|||
|
public const short FW_ULTRABOLD = FW_EXTRABOLD;
|
|||
|
public const short FW_BLACK = FW_HEAVY;
|
|||
|
|
|||
|
// PARAFORMAT mask values
|
|||
|
public const UInt32 PFM_STARTINDENT = 0x00000001;
|
|||
|
public const UInt32 PFM_RIGHTINDENT = 0x00000002;
|
|||
|
public const UInt32 PFM_OFFSET = 0x00000004;
|
|||
|
public const UInt32 PFM_ALIGNMENT = 0x00000008;
|
|||
|
public const UInt32 PFM_TABSTOPS = 0x00000010;
|
|||
|
public const UInt32 PFM_NUMBERING = 0x00000020;
|
|||
|
public const UInt32 PFM_OFFSETINDENT = 0x80000000;
|
|||
|
|
|||
|
// PARAFORMAT numbering options
|
|||
|
public const UInt16 PFN_BULLET = 0x0001;
|
|||
|
|
|||
|
// PARAFORMAT alignment options
|
|||
|
public const UInt16 PFA_LEFT = 0x0001;
|
|||
|
public const UInt16 PFA_RIGHT = 0x0002;
|
|||
|
public const UInt16 PFA_CENTER = 0x0003;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// It makes no difference if we use PARAFORMAT or
|
|||
|
// PARAFORMAT2 here, so I have opted for PARAFORMAT2.
|
|||
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
public 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)]
|
|||
|
public struct CHARFORMAT
|
|||
|
{
|
|||
|
public int cbSize;
|
|||
|
public UInt32 dwMask;
|
|||
|
public UInt32 dwEffects;
|
|||
|
public Int32 yHeight;
|
|||
|
public Int32 yOffset;
|
|||
|
public Int32 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 Int32 crBackColor;
|
|||
|
public uint lcid;
|
|||
|
public uint dwReserved;
|
|||
|
public short sStyle;
|
|||
|
public short wKerning;
|
|||
|
public byte bUnderlineType;
|
|||
|
public byte bAnimation;
|
|||
|
public byte bRevAuthor;
|
|||
|
public byte bReserved1;
|
|||
|
}
|
|||
|
|
|||
|
[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 PARAFORMAT lp);
|
|||
|
|
|||
|
[DllImport("user32", CharSet = CharSet.Auto)]
|
|||
|
private static extern int SendMessage(HandleRef hWnd,
|
|||
|
int msg,
|
|||
|
int wParam,
|
|||
|
ref CHARFORMAT lp);
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
//----------------------------
|
|||
|
// New, version 1.1
|
|||
|
public void SetSuperScript(bool bSet)
|
|||
|
{
|
|||
|
CHARFORMAT cf = this.CharFormat;
|
|||
|
|
|||
|
if (bSet)
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_SUPERSCRIPT;
|
|||
|
cf.dwEffects |= CFE_SUPERSCRIPT;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFE_SUPERSCRIPT;
|
|||
|
}
|
|||
|
|
|||
|
this.CharFormat = cf;
|
|||
|
}
|
|||
|
|
|||
|
public void SetSubScript(bool bSet)
|
|||
|
{
|
|||
|
CHARFORMAT cf = this.CharFormat;
|
|||
|
|
|||
|
if (bSet)
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_SUBSCRIPT;
|
|||
|
cf.dwEffects |= CFE_SUBSCRIPT;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFE_SUBSCRIPT;
|
|||
|
}
|
|||
|
|
|||
|
this.CharFormat = cf;
|
|||
|
}
|
|||
|
|
|||
|
public bool IsSuperScript()
|
|||
|
{
|
|||
|
CHARFORMAT cf = this.CharFormat;
|
|||
|
return ((cf.dwEffects & CFE_SUPERSCRIPT) == CFE_SUPERSCRIPT);
|
|||
|
}
|
|||
|
|
|||
|
public bool IsSubScript()
|
|||
|
{
|
|||
|
CHARFORMAT cf = this.CharFormat;
|
|||
|
return ((cf.dwEffects & CFE_SUBSCRIPT) == CFE_SUBSCRIPT);
|
|||
|
}
|
|||
|
//----------------------------
|
|||
|
|
|||
|
public PARAFORMAT ParaFormat
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
PARAFORMAT pf = new PARAFORMAT();
|
|||
|
pf.cbSize = Marshal.SizeOf(pf);
|
|||
|
|
|||
|
// Get the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_GETPARAFORMAT,
|
|||
|
SCF_SELECTION, ref pf);
|
|||
|
|
|||
|
return pf;
|
|||
|
}
|
|||
|
|
|||
|
set
|
|||
|
{
|
|||
|
PARAFORMAT pf = value;
|
|||
|
pf.cbSize = Marshal.SizeOf(pf);
|
|||
|
|
|||
|
// Set the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_SETPARAFORMAT,
|
|||
|
SCF_SELECTION, ref pf);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public PARAFORMAT DefaultParaFormat
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
PARAFORMAT pf = new PARAFORMAT();
|
|||
|
pf.cbSize = Marshal.SizeOf(pf);
|
|||
|
|
|||
|
// Get the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_GETPARAFORMAT,
|
|||
|
SCF_ALL, ref pf);
|
|||
|
|
|||
|
return pf;
|
|||
|
}
|
|||
|
|
|||
|
set
|
|||
|
{
|
|||
|
PARAFORMAT pf = value;
|
|||
|
pf.cbSize = Marshal.SizeOf(pf);
|
|||
|
|
|||
|
// Set the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_SETPARAFORMAT,
|
|||
|
SCF_ALL, ref pf);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public CHARFORMAT CharFormat
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
CHARFORMAT cf = new CHARFORMAT();
|
|||
|
cf.cbSize = Marshal.SizeOf(cf);
|
|||
|
|
|||
|
// Get the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_GETCHARFORMAT,
|
|||
|
SCF_SELECTION, ref cf);
|
|||
|
|
|||
|
return cf;
|
|||
|
}
|
|||
|
|
|||
|
set
|
|||
|
{
|
|||
|
CHARFORMAT cf = value;
|
|||
|
cf.cbSize = Marshal.SizeOf(cf);
|
|||
|
|
|||
|
// Set the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_SETCHARFORMAT,
|
|||
|
SCF_SELECTION, ref cf);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public CHARFORMAT DefaultCharFormat
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
CHARFORMAT cf = new CHARFORMAT();
|
|||
|
cf.cbSize = Marshal.SizeOf(cf);
|
|||
|
|
|||
|
// Get the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_GETCHARFORMAT,
|
|||
|
SCF_ALL, ref cf);
|
|||
|
|
|||
|
return cf;
|
|||
|
}
|
|||
|
|
|||
|
set
|
|||
|
{
|
|||
|
CHARFORMAT cf = value;
|
|||
|
cf.cbSize = Marshal.SizeOf(cf);
|
|||
|
|
|||
|
// Set the alignment.
|
|||
|
SendMessage(new HandleRef(this, Handle),
|
|||
|
EM_SETCHARFORMAT,
|
|||
|
SCF_ALL, ref cf);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#region COLORREF helper functions
|
|||
|
|
|||
|
// convert COLORREF to Color
|
|||
|
private Color GetColor(int crColor)
|
|||
|
{
|
|||
|
byte r = (byte)(crColor);
|
|||
|
byte g = (byte)(crColor >> 8);
|
|||
|
byte b = (byte)(crColor >> 16);
|
|||
|
|
|||
|
return Color.FromArgb(r, g, b);
|
|||
|
}
|
|||
|
|
|||
|
// convert COLORREF to Color
|
|||
|
private int GetCOLORREF(int r, int g, int b)
|
|||
|
{
|
|||
|
int r2 = r;
|
|||
|
int g2 = (g << 8);
|
|||
|
int b2 = (b << 16);
|
|||
|
|
|||
|
int result = r2 | g2 | b2;
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private int GetCOLORREF(Color color)
|
|||
|
{
|
|||
|
int r = color.R;
|
|||
|
int g = color.G;
|
|||
|
int b = color.B;
|
|||
|
|
|||
|
return GetCOLORREF(r, g, b);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
#region "Get HTML text"
|
|||
|
|
|||
|
// format states
|
|||
|
private enum ctformatStates
|
|||
|
{
|
|||
|
nctNone = 0, // none format applied
|
|||
|
nctNew = 1, // new format
|
|||
|
nctContinue = 2, // continue with previous format
|
|||
|
nctReset = 3 // reset format (close this tag)
|
|||
|
}
|
|||
|
|
|||
|
private enum uMyREType
|
|||
|
{
|
|||
|
U_MYRE_TYPE_TAG,
|
|||
|
U_MYRE_TYPE_EMO,
|
|||
|
U_MYRE_TYPE_ENTITY,
|
|||
|
}
|
|||
|
|
|||
|
private struct cMyREFormat
|
|||
|
{
|
|||
|
public uMyREType nType;
|
|||
|
public int nLen;
|
|||
|
public int nPos;
|
|||
|
public string strValue;
|
|||
|
}
|
|||
|
|
|||
|
public string GetHTML(bool bHTML, bool bParaFormat)
|
|||
|
{
|
|||
|
//------------------------
|
|||
|
// working variables
|
|||
|
CHARFORMAT cf;
|
|||
|
PARAFORMAT pf;
|
|||
|
|
|||
|
ctformatStates bold = ctformatStates.nctNone;
|
|||
|
ctformatStates bitalic = ctformatStates.nctNone;
|
|||
|
ctformatStates bstrikeout = ctformatStates.nctNone;
|
|||
|
ctformatStates bunderline = ctformatStates.nctNone;
|
|||
|
ctformatStates super = ctformatStates.nctNone;
|
|||
|
ctformatStates sub = ctformatStates.nctNone;
|
|||
|
|
|||
|
ctformatStates bacenter = ctformatStates.nctNone;
|
|||
|
ctformatStates baleft = ctformatStates.nctNone;
|
|||
|
ctformatStates baright = ctformatStates.nctNone;
|
|||
|
ctformatStates bnumbering = ctformatStates.nctNone;
|
|||
|
|
|||
|
string strFont = "";
|
|||
|
Int32 crFont = 0;
|
|||
|
Color color = new Color();
|
|||
|
int yHeight = 0;
|
|||
|
int i = 0;
|
|||
|
//-------------------------
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// to store formatting
|
|||
|
ArrayList colFormat = new ArrayList();
|
|||
|
|
|||
|
cMyREFormat mfr;
|
|||
|
//-------------------------
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// ok, lets go
|
|||
|
int nStart, nEnd;
|
|||
|
string strHTML = "";
|
|||
|
|
|||
|
this.HideSelection = true;
|
|||
|
this.BeginUpdate();
|
|||
|
|
|||
|
nStart = this.SelectionStart;
|
|||
|
nEnd = this.SelectionLength;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
//--------------------------------
|
|||
|
// replace entities
|
|||
|
if (bHTML)
|
|||
|
{
|
|||
|
|
|||
|
char[] ch = { '&', '<', '>', '"', '\'' };
|
|||
|
string[] strreplace = { "&", "<", ">", """, "'" };
|
|||
|
|
|||
|
for (i = 0; i < ch.Length; i++)
|
|||
|
{
|
|||
|
char[] ch2 = { ch[i] };
|
|||
|
|
|||
|
int n = this.Find(ch2, 0);
|
|||
|
while (n != -1)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = n;
|
|||
|
mfr.nLen = 1;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_ENTITY;
|
|||
|
mfr.strValue = strreplace[i];
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
n = this.Find(ch2, n + 1);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
//--------------------------------
|
|||
|
|
|||
|
string strT = "";
|
|||
|
|
|||
|
int k = this.TextLength;
|
|||
|
char[] chtrim = { ' ', '\x0000' };
|
|||
|
|
|||
|
//--------------------------------
|
|||
|
// this is an inefficient method to get text format
|
|||
|
// but RichTextBox doesn't provide another method to
|
|||
|
// get something like an array of charformat and paraformat
|
|||
|
//--------------------------------
|
|||
|
for (i = 0; i < k; i++)
|
|||
|
{
|
|||
|
// select one character
|
|||
|
this.Select(i, 1);
|
|||
|
string strChar = this.SelectedText;
|
|||
|
|
|||
|
if (bHTML)
|
|||
|
{
|
|||
|
//-------------------------
|
|||
|
// get format for this character
|
|||
|
cf = this.CharFormat;
|
|||
|
pf = this.ParaFormat;
|
|||
|
|
|||
|
string strfname = new string(cf.szFaceName);
|
|||
|
strfname = strfname.Trim(chtrim);
|
|||
|
//-------------------------
|
|||
|
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// new font format ?
|
|||
|
if ((strFont != strfname) || (crFont != cf.crTextColor) || (yHeight != cf.yHeight))
|
|||
|
{
|
|||
|
if (strFont != "")
|
|||
|
{
|
|||
|
// close previous <font> tag
|
|||
|
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</font>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// save this for cache
|
|||
|
strFont = strfname;
|
|||
|
crFont = cf.crTextColor;
|
|||
|
yHeight = cf.yHeight;
|
|||
|
//-------------------------
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// font size should be translate to
|
|||
|
// html size (Approximately)
|
|||
|
double fsize = (double)yHeight / (double)(20 * 5);
|
|||
|
|
|||
|
//-------------------------
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// color object from COLORREF
|
|||
|
color = GetColor(crFont);
|
|||
|
//-------------------------
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// add <font> tag
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
string strcolor = string.Concat("#", (color.ToArgb() & 0x00FFFFFF).ToString("X6"));
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<font face=\"" + strFont + "\" color=\"" + strcolor + "\" size=\"" + fsize + "\">";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
//-------------------------
|
|||
|
}
|
|||
|
|
|||
|
//-------------------------
|
|||
|
// are we in another line ?
|
|||
|
if ((strChar == "\r") || (strChar == "\n"))
|
|||
|
{
|
|||
|
// yes?
|
|||
|
// then, we need to reset paragraph format
|
|||
|
// and character format
|
|||
|
if (bParaFormat)
|
|||
|
{
|
|||
|
bnumbering = ctformatStates.nctNone;
|
|||
|
baleft = ctformatStates.nctNone;
|
|||
|
baright = ctformatStates.nctNone;
|
|||
|
bacenter = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
|
|||
|
// close previous tags
|
|||
|
|
|||
|
// is italic? => close it
|
|||
|
if (bitalic != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</i>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bitalic = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
|
|||
|
// is bold? => close it
|
|||
|
if (bold != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</b>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bold = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
|
|||
|
// is underline? => close it
|
|||
|
if (bunderline != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</u>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bunderline = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
|
|||
|
// is strikeout? => close it
|
|||
|
if (bstrikeout != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</s>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bstrikeout = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
|
|||
|
// is super? => close it
|
|||
|
if (super != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</sup>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
super = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
|
|||
|
// is sub? => close it
|
|||
|
if (sub != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</sub>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
sub = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// now, process the paragraph format,
|
|||
|
// managing states: none, new, continue {with previous}, reset
|
|||
|
if (bParaFormat)
|
|||
|
{
|
|||
|
// align to center?
|
|||
|
if (pf.wAlignment == PFA_CENTER)
|
|||
|
{
|
|||
|
if (bacenter == ctformatStates.nctNone)
|
|||
|
bacenter = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
bacenter = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bacenter != ctformatStates.nctNone)
|
|||
|
bacenter = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (bacenter == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<p align=\"center\">";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (bacenter == ctformatStates.nctReset)
|
|||
|
bacenter = ctformatStates.nctNone;
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// align to left ?
|
|||
|
if (pf.wAlignment == PFA_LEFT)
|
|||
|
{
|
|||
|
if (baleft == ctformatStates.nctNone)
|
|||
|
baleft = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
baleft = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (baleft != ctformatStates.nctNone)
|
|||
|
baleft = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (baleft == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<p align=\"left\">";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (baleft == ctformatStates.nctReset)
|
|||
|
baleft = ctformatStates.nctNone;
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// align to right ?
|
|||
|
if (pf.wAlignment == PFA_RIGHT)
|
|||
|
{
|
|||
|
if (baright == ctformatStates.nctNone)
|
|||
|
baright = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
baright = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (baright != ctformatStates.nctNone)
|
|||
|
baright = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (baright == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<p align=\"right\">";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (baright == ctformatStates.nctReset)
|
|||
|
baright = ctformatStates.nctNone;
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// bullet ?
|
|||
|
if (pf.wNumbering == PFN_BULLET)
|
|||
|
{
|
|||
|
if (bnumbering == ctformatStates.nctNone)
|
|||
|
bnumbering = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
bnumbering = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bnumbering != ctformatStates.nctNone)
|
|||
|
bnumbering = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (bnumbering == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<li>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (bnumbering == ctformatStates.nctReset)
|
|||
|
bnumbering = ctformatStates.nctNone;
|
|||
|
//---------------------
|
|||
|
}
|
|||
|
|
|||
|
//---------------------
|
|||
|
// bold ?
|
|||
|
if ((cf.dwEffects & CFE_BOLD) == CFE_BOLD)
|
|||
|
{
|
|||
|
if (bold == ctformatStates.nctNone)
|
|||
|
bold = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
bold = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bold != ctformatStates.nctNone)
|
|||
|
bold = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (bold == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<b>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (bold == ctformatStates.nctReset)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</b>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bold = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// Italic
|
|||
|
if ((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC)
|
|||
|
{
|
|||
|
if (bitalic == ctformatStates.nctNone)
|
|||
|
bitalic = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
bitalic = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bitalic != ctformatStates.nctNone)
|
|||
|
bitalic = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (bitalic == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<i>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (bitalic == ctformatStates.nctReset)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</i>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bitalic = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// strikeout
|
|||
|
if ((cf.dwEffects & CFM_STRIKEOUT) == CFM_STRIKEOUT)
|
|||
|
{
|
|||
|
if (bstrikeout == ctformatStates.nctNone)
|
|||
|
bstrikeout = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
bstrikeout = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bstrikeout != ctformatStates.nctNone)
|
|||
|
bstrikeout = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (bstrikeout == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<s>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (bstrikeout == ctformatStates.nctReset)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</s>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bstrikeout = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// underline ?
|
|||
|
if ((cf.dwEffects & CFE_UNDERLINE) == CFE_UNDERLINE)
|
|||
|
{
|
|||
|
if (bunderline == ctformatStates.nctNone)
|
|||
|
bunderline = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
bunderline = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (bunderline != ctformatStates.nctNone)
|
|||
|
bunderline = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (bunderline == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<u>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (bunderline == ctformatStates.nctReset)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</u>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
bunderline = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// superscript ?
|
|||
|
if ((cf.dwEffects & CFE_SUPERSCRIPT) == CFE_SUPERSCRIPT)
|
|||
|
{
|
|||
|
if (super == ctformatStates.nctNone)
|
|||
|
super = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
super = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (super != ctformatStates.nctNone)
|
|||
|
super = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (super == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<sup>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (super == ctformatStates.nctReset)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</sup>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
super = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
//---------------------
|
|||
|
|
|||
|
//---------------------
|
|||
|
// subscript ?
|
|||
|
if ((cf.dwEffects & CFE_SUBSCRIPT) == CFE_SUBSCRIPT)
|
|||
|
{
|
|||
|
if (sub == ctformatStates.nctNone)
|
|||
|
sub = ctformatStates.nctNew;
|
|||
|
else
|
|||
|
sub = ctformatStates.nctContinue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (sub != ctformatStates.nctNone)
|
|||
|
sub = ctformatStates.nctReset;
|
|||
|
}
|
|||
|
|
|||
|
if (sub == ctformatStates.nctNew)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "<sub>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
else if (sub == ctformatStates.nctReset)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</sub>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
sub = ctformatStates.nctNone;
|
|||
|
}
|
|||
|
//---------------------
|
|||
|
}
|
|||
|
|
|||
|
strT += strChar;
|
|||
|
}
|
|||
|
|
|||
|
if (bHTML)
|
|||
|
{
|
|||
|
// close pending tags
|
|||
|
if (bold != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</b>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
//strT += "</b>";
|
|||
|
}
|
|||
|
|
|||
|
if (bitalic != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</i>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
//strT += "</i>";
|
|||
|
}
|
|||
|
|
|||
|
if (bstrikeout != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</s>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
//strT += "</s>";
|
|||
|
}
|
|||
|
|
|||
|
if (bunderline != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</u>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
|
|||
|
//strT += "</u>";
|
|||
|
}
|
|||
|
|
|||
|
if (super != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</sup>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
//strT += "</sup>";
|
|||
|
}
|
|||
|
|
|||
|
if (sub != ctformatStates.nctNone)
|
|||
|
{
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</sub>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
//strT += "</sub>";
|
|||
|
}
|
|||
|
|
|||
|
if (strFont != "")
|
|||
|
{
|
|||
|
// close pending font format
|
|||
|
mfr = new cMyREFormat();
|
|||
|
|
|||
|
mfr.nPos = i;
|
|||
|
mfr.nLen = 0;
|
|||
|
mfr.nType = uMyREType.U_MYRE_TYPE_TAG;
|
|||
|
mfr.strValue = "</font>";
|
|||
|
|
|||
|
colFormat.Add(mfr);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//--------------------------
|
|||
|
// now, reorder the formatting array
|
|||
|
k = colFormat.Count;
|
|||
|
for (i = 0; i < k - 1; i++)
|
|||
|
{
|
|||
|
for (int j = i + 1; j < k; j++)
|
|||
|
{
|
|||
|
mfr = (cMyREFormat)colFormat[i];
|
|||
|
cMyREFormat mfr2 = (cMyREFormat)colFormat[j];
|
|||
|
|
|||
|
if (mfr2.nPos < mfr.nPos)
|
|||
|
{
|
|||
|
colFormat.RemoveAt(j);
|
|||
|
colFormat.Insert(i, mfr2);
|
|||
|
j--;
|
|||
|
}
|
|||
|
else if ((mfr2.nPos == mfr.nPos) && (mfr2.nLen < mfr.nLen))
|
|||
|
{
|
|||
|
colFormat.RemoveAt(j);
|
|||
|
colFormat.Insert(i, mfr2);
|
|||
|
j--;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
//--------------------------
|
|||
|
|
|||
|
|
|||
|
//--------------------------
|
|||
|
// apply format by replacing and inserting HTML tags
|
|||
|
// stored in the Format Array
|
|||
|
int nAcum = 0;
|
|||
|
for (i = 0; i < k; i++)
|
|||
|
{
|
|||
|
mfr = (cMyREFormat)colFormat[i];
|
|||
|
|
|||
|
strHTML += strT.Substring(nAcum, mfr.nPos - nAcum) + mfr.strValue;
|
|||
|
nAcum = mfr.nPos + mfr.nLen;
|
|||
|
}
|
|||
|
|
|||
|
if (nAcum < strT.Length)
|
|||
|
strHTML += strT.Substring(nAcum);
|
|||
|
//--------------------------
|
|||
|
}
|
|||
|
catch
|
|||
|
{
|
|||
|
//MessageBox.Show(ex.Message);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
//--------------------------
|
|||
|
// finish, restore
|
|||
|
this.SelectionStart = nStart;
|
|||
|
this.SelectionLength = nEnd;
|
|||
|
|
|||
|
this.EndUpdate();
|
|||
|
this.HideSelection = false;
|
|||
|
//--------------------------
|
|||
|
}
|
|||
|
|
|||
|
return strHTML;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region "Add HTML text"
|
|||
|
public void AddHTML(string strHTML)
|
|||
|
{
|
|||
|
CHARFORMAT cf;
|
|||
|
PARAFORMAT pf;
|
|||
|
|
|||
|
cf = this.DefaultCharFormat; // to apply character formatting
|
|||
|
pf = this.DefaultParaFormat; // to apply paragraph formatting
|
|||
|
|
|||
|
char[] chtrim = { ' ', '\x0000' };
|
|||
|
|
|||
|
this.HideSelection = true;
|
|||
|
this.BeginUpdate();
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
// process text
|
|||
|
while (strHTML.Length > 0)
|
|||
|
{
|
|||
|
string strData = strHTML;
|
|||
|
|
|||
|
reinit:
|
|||
|
|
|||
|
// looking for start tags
|
|||
|
int nStart = strHTML.IndexOf('<');
|
|||
|
if (nStart >= 0)
|
|||
|
{
|
|||
|
if (nStart > 0)
|
|||
|
{
|
|||
|
// tag is not the first character, so
|
|||
|
// we need to add text to control and continue
|
|||
|
// looking for tags at the begining of the text
|
|||
|
strData = strHTML.Substring(0, nStart);
|
|||
|
strHTML = strHTML.Substring(nStart);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// ok, get tag value
|
|||
|
int nEnd = strHTML.IndexOf('>', nStart);
|
|||
|
if (nEnd > nStart)
|
|||
|
{
|
|||
|
if ((nEnd - nStart) > 0)
|
|||
|
{
|
|||
|
string strTag = strHTML.Substring(nStart, nEnd - nStart + 1);
|
|||
|
strTag = strTag.ToLower();
|
|||
|
|
|||
|
if (strTag == "<b>")
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_WEIGHT | CFM_BOLD;
|
|||
|
cf.dwEffects |= CFE_BOLD;
|
|||
|
cf.wWeight = FW_BOLD;
|
|||
|
}
|
|||
|
else if (strTag == "<i>")
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_ITALIC;
|
|||
|
cf.dwEffects |= CFE_ITALIC;
|
|||
|
}
|
|||
|
else if (strTag == "<u>")
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_UNDERLINE | CFM_UNDERLINETYPE;
|
|||
|
cf.dwEffects |= CFE_UNDERLINE;
|
|||
|
cf.bUnderlineType = CFU_UNDERLINE;
|
|||
|
}
|
|||
|
else if (strTag == "<s>")
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_STRIKEOUT;
|
|||
|
cf.dwEffects |= CFE_STRIKEOUT;
|
|||
|
}
|
|||
|
else if (strTag == "<sup>")
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_SUPERSCRIPT;
|
|||
|
cf.dwEffects |= CFE_SUPERSCRIPT;
|
|||
|
}
|
|||
|
else if (strTag == "<sub>")
|
|||
|
{
|
|||
|
cf.dwMask |= CFM_SUBSCRIPT;
|
|||
|
cf.dwEffects |= CFE_SUBSCRIPT;
|
|||
|
}
|
|||
|
else if ((strTag.Length > 2) && (strTag.Substring(0, 2) == "<p"))
|
|||
|
{
|
|||
|
if (strTag.IndexOf("align=\"left\"") > 0)
|
|||
|
{
|
|||
|
pf.dwMask |= PFM_ALIGNMENT;
|
|||
|
pf.wAlignment = (short)PFA_LEFT;
|
|||
|
}
|
|||
|
else if (strTag.IndexOf("align=\"right\"") > 0)
|
|||
|
{
|
|||
|
pf.dwMask |= PFM_ALIGNMENT;
|
|||
|
pf.wAlignment = (short)PFA_RIGHT;
|
|||
|
}
|
|||
|
else if (strTag.IndexOf("align=\"center\"") > 0)
|
|||
|
{
|
|||
|
pf.dwMask |= PFM_ALIGNMENT;
|
|||
|
pf.wAlignment = (short)PFA_CENTER;
|
|||
|
}
|
|||
|
}
|
|||
|
else if ((strTag.Length > 5) && (strTag.Substring(0, 5) == "<font"))
|
|||
|
{
|
|||
|
string strFont = new string(cf.szFaceName);
|
|||
|
strFont = strFont.Trim(chtrim);
|
|||
|
int crFont = cf.crTextColor;
|
|||
|
int yHeight = cf.yHeight;
|
|||
|
double dHeight = yHeight;
|
|||
|
int nFace = strTag.IndexOf("face=");
|
|||
|
if (nFace > 0)
|
|||
|
{
|
|||
|
int nFaceEnd = strTag.IndexOf('\"', nFace + 6);
|
|||
|
if (nFaceEnd > nFace)
|
|||
|
strFont = strTag.Substring(nFace + 6, nFaceEnd - nFace - 6);
|
|||
|
}
|
|||
|
|
|||
|
int nSize = strTag.IndexOf("size=");
|
|||
|
if (nSize > 0)
|
|||
|
{
|
|||
|
int nSizeEnd = strTag.IndexOf('\"', nSize + 6);
|
|||
|
if (nSizeEnd > nSize)
|
|||
|
{
|
|||
|
dHeight = double.Parse(strTag.Substring(nSize + 6, nSizeEnd - nSize - 6));
|
|||
|
dHeight *= (double)(20 * 5);
|
|||
|
yHeight = (int)dHeight;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int nColor = strTag.IndexOf("color=");
|
|||
|
if (nColor > 0)
|
|||
|
{
|
|||
|
int nColorEnd = strTag.IndexOf('\"', nColor + 7);
|
|||
|
if (nColorEnd > nColor)
|
|||
|
{
|
|||
|
if (strTag.Substring(nColor + 7, 1) == "#")
|
|||
|
{
|
|||
|
string strCr = strTag.Substring(nColor + 8, nColorEnd - nColor - 8);
|
|||
|
int nCr = Convert.ToInt32(strCr, 16);
|
|||
|
|
|||
|
Color color = Color.FromArgb(nCr);
|
|||
|
|
|||
|
crFont = GetCOLORREF(color);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
crFont = int.Parse(strTag.Substring(nColor + 7, nColorEnd - nColor - 7));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
cf.szFaceName = new char[LF_FACESIZE];
|
|||
|
strFont.CopyTo(0, cf.szFaceName, 0, Math.Min(LF_FACESIZE - 1, strFont.Length));
|
|||
|
//cf.szFaceName = strFont.ToCharArray(0, Math.Min(strFont.Length, LF_FACESIZE));
|
|||
|
cf.crTextColor = crFont;
|
|||
|
cf.yHeight = yHeight;
|
|||
|
|
|||
|
cf.dwMask |= CFM_COLOR | CFM_SIZE | CFM_FACE;
|
|||
|
cf.dwEffects &= ~CFE_AUTOCOLOR;
|
|||
|
}
|
|||
|
else if (strTag == "<li>")
|
|||
|
{
|
|||
|
if (pf.wNumbering != PFN_BULLET)
|
|||
|
{
|
|||
|
pf.dwMask |= PFM_NUMBERING;
|
|||
|
pf.wNumbering = (short)PFN_BULLET;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (strTag == "</b>")
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFE_BOLD;
|
|||
|
cf.wWeight = FW_NORMAL;
|
|||
|
}
|
|||
|
else if (strTag == "</i>")
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFE_ITALIC;
|
|||
|
}
|
|||
|
else if (strTag == "</u>")
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFE_UNDERLINE;
|
|||
|
}
|
|||
|
else if (strTag == "</s>")
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFM_STRIKEOUT;
|
|||
|
}
|
|||
|
else if (strTag == "</sup>")
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFE_SUPERSCRIPT;
|
|||
|
}
|
|||
|
else if (strTag == "</sub>")
|
|||
|
{
|
|||
|
cf.dwEffects &= ~CFE_SUBSCRIPT;
|
|||
|
}
|
|||
|
else if (strTag == "</font>")
|
|||
|
{
|
|||
|
}
|
|||
|
else if (strTag == "</p>")
|
|||
|
{
|
|||
|
}
|
|||
|
else if (strTag == "</li>")
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
//-------------------------------
|
|||
|
// now, remove tag from HTML
|
|||
|
int nStart2 = strHTML.IndexOf("<", nEnd + 1);
|
|||
|
if (nStart2 > 0)
|
|||
|
{
|
|||
|
// extract partial data
|
|||
|
strData = strHTML.Substring(nEnd + 1, nStart2 - nEnd - 1);
|
|||
|
strHTML = strHTML.Substring(nStart2);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// get remain text and finish
|
|||
|
if ((nEnd + 1) < strHTML.Length)
|
|||
|
strData = strHTML.Substring(nEnd + 1);
|
|||
|
else
|
|||
|
strData = "";
|
|||
|
|
|||
|
strHTML = "";
|
|||
|
}
|
|||
|
//-------------------------------s
|
|||
|
|
|||
|
|
|||
|
//-------------------------------
|
|||
|
// have we any continuos tag ?
|
|||
|
if (strData.Length > 0)
|
|||
|
{
|
|||
|
// yes, ok, goto to reinit
|
|||
|
if (strData[0] == '<')
|
|||
|
goto reinit;
|
|||
|
}
|
|||
|
//-------------------------------
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// we have not found any valid tag
|
|||
|
strHTML = "";
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// we have not found any valid tag
|
|||
|
strHTML = "";
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// we have not found any tag
|
|||
|
strHTML = "";
|
|||
|
}
|
|||
|
|
|||
|
if (strData.Length > 0)
|
|||
|
{
|
|||
|
//-------------------------------
|
|||
|
// replace entities
|
|||
|
strData = strData.Replace("&", "&");
|
|||
|
strData = strData.Replace("<", "<");
|
|||
|
strData = strData.Replace(">", ">");
|
|||
|
strData = strData.Replace("'", "'");
|
|||
|
strData = strData.Replace(""", "\"");
|
|||
|
//-------------------------------
|
|||
|
|
|||
|
string strAux = strData; // use another copy
|
|||
|
|
|||
|
while (strAux.Length > 0)
|
|||
|
{
|
|||
|
//-----------------------
|
|||
|
int nLen = strAux.Length;
|
|||
|
//-----------------------
|
|||
|
|
|||
|
//-------------------------------
|
|||
|
// now, add text to control
|
|||
|
int nStartCache = this.SelectionStart;
|
|||
|
string strt = strAux.Substring(0, nLen);
|
|||
|
|
|||
|
this.SelectedText = strt;
|
|||
|
strAux = strAux.Remove(0, nLen);
|
|||
|
|
|||
|
this.SelectionStart = nStartCache;
|
|||
|
this.SelectionLength = strt.Length;
|
|||
|
//-------------------------------
|
|||
|
|
|||
|
//-------------------------------
|
|||
|
// apply format
|
|||
|
this.ParaFormat = pf;
|
|||
|
this.CharFormat = cf;
|
|||
|
//-------------------------------
|
|||
|
|
|||
|
|
|||
|
// reposition to final
|
|||
|
this.SelectionStart = this.TextLength + 1;
|
|||
|
this.SelectionLength = 0;
|
|||
|
}
|
|||
|
|
|||
|
// reposition to final
|
|||
|
this.SelectionStart = this.TextLength + 1;
|
|||
|
this.SelectionLength = 0;
|
|||
|
|
|||
|
//-------------------------------
|
|||
|
// new paragraph requires to reset alignment
|
|||
|
if ((strData.IndexOf("\r\n", 0) >= 0) || (strData.IndexOf("\n", 0) >= 0))
|
|||
|
{
|
|||
|
pf.dwMask = PFM_ALIGNMENT | PFM_NUMBERING;
|
|||
|
pf.wAlignment = (short)PFA_LEFT;
|
|||
|
pf.wNumbering = 0;
|
|||
|
}
|
|||
|
//-------------------------------
|
|||
|
}
|
|||
|
} // while (strHTML.Length > 0)
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
MessageBox.Show(ex.Message);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
// reposition to final
|
|||
|
this.SelectionStart = this.TextLength + 1;
|
|||
|
this.SelectionLength = 0;
|
|||
|
|
|||
|
this.EndUpdate();
|
|||
|
this.HideSelection = false;
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
}
|
|||
|
}
|