Exferia/Exferia_Controles/Exferia_Controles/Exferia_TextboxHTML.cs

860 lines
29 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MSHTML;
namespace Exferia_Controles
{
public partial class Exferia_TextboxHTML : UserControl
{
#region Variables privadas
private IHTMLDocument2 g_obj_IHTMLDocument2;
private bool g_bol_Timer_Iniciado = false;
private DateTime g_dtt_UltimaEntrada = DateTime.Now;
private bool g_bol_Configuracion = false;
private bool g_bol_Actualizando_NombreFuente = false;
private bool g_bol_Actualizando_DimensionFuente = false;
private bool g_bol_SeAplicoEstilo=false;
#endregion
#region Propiedad Publicas
[Browsable(false)]
public string Exferia_TextboxHTML_HTML
{
get
{
if (wbr_Principal.DocumentText != null)
{
string str_HTML = wbr_Principal.DocumentText;
if (str_HTML != null)
{
//Quitar parrafos
/*str_HTML = str_HTML.Replace("<P", "<div");
str_HTML = str_HTML.Replace("</P>", "</div>");
//JUstificar
str_HTML = str_HTML.Replace("align=center", " align: center;\"");
str_HTML = str_HTML.Replace("align=left", " align: left;\"");
str_HTML = str_HTML.Replace("align=right", " align: right;\"");
str_HTML = str_HTML.Replace("align=justify", " align: justify;\"");
str_HTML = str_HTML.Replace("align:", " style = \"text-align:");*/
/*//Tamaño de fuentes
str_HTML = str_HTML.Replace("<FONT size=", "<FONT style = \"font-size:");
for (int int_Contador = 1; int_Contador < 20; int_Contador++)
{
str_HTML = str_HTML.Replace("<FONT style = \"font-size:" + int_Contador, "<FONT style = \"font-size:" + int_Contador + "px\"");
}*/
}
return str_HTML;
}
else
return string.Empty;
}
set
{
if (wbr_Principal.DocumentText != null)
wbr_Principal.DocumentText = value;
}
}
public string Exferia_TextboxHTML_CuerpoHTML
{
get
{
if (wbr_Principal.Document != null &&
wbr_Principal.Document.Body != null)
{
return wbr_Principal.Document.Body.InnerHtml;
}
else
return string.Empty;
}
set
{
if (wbr_Principal.Document.Body != null)
wbr_Principal.Document.Body.InnerHtml = value;
}
}
public void Exferia_TextboxHTML_Limpiar()
{
if (wbr_Principal.Document.Body != null)
wbr_Principal.Document.Body.InnerHtml = "";
}
#endregion
#region Eventos Privados
public event MethodInvoker g_evt_Negrita_Changed;
public event MethodInvoker g_evt_Italica_Changed;
public event MethodInvoker g_evt_Subrayado_Changed;
public event MethodInvoker g_evt_Numeracion_Changed;
public event MethodInvoker g_evt_Listado_Changed;
public event MethodInvoker g_evt_JustificadoIzquierda_Changed;
public event MethodInvoker g_evt_JustificadoCentro_Changed;
public event MethodInvoker g_evt_JustificadoDerecha_Changed;
public event MethodInvoker g_evt_JustificadoCompleto_Changed;
public event MethodInvoker g_evt_HtmlFuenteNombre_Changed;
public event MethodInvoker g_evt_HtmlFuenteDimension_Changed;
#endregion
#region Eventos publicos
public event EventHandler<EnterKeyEventArgs> g_evt_EnterKeyEvent;
public class EnterKeyEventArgs : EventArgs
{
private bool _cancel = false;
public bool Cancel
{
get { return _cancel; }
set { _cancel = value; }
}
}
public delegate void TickDelegate();
public event TickDelegate g_evt_Tick;
public event EventHandler Exferia_TextboxHTML_Evento_GotFocus;
public event EventHandler Exferia_TextboxHTML_Evento_LostFocus;
public void Pegar_Texto_Portapapeles()
{
wbr_Principal.Focus();
wbr_Principal.Document.ExecCommand("Paste", false, null);
}
#endregion
#region Constructor
public Exferia_TextboxHTML()
{
InitializeComponent();
Configurar_Eventos();
Configurar_Timer();
Configurar_Navegador();
Configurar_Fuente_Nombres();
Configurar_Fuente_Dimension();
btn_Negrita.CheckedChanged += delegate
{
if (g_evt_Negrita_Changed != null)
g_evt_Negrita_Changed();
};
btn_Italica.CheckedChanged += delegate
{
if (g_evt_Italica_Changed != null)
g_evt_Italica_Changed();
};
btn_Subrayado.CheckedChanged += delegate
{
if (g_evt_Subrayado_Changed != null)
g_evt_Subrayado_Changed();
};
btn_Numeracion.CheckedChanged += delegate
{
if (g_evt_Numeracion_Changed != null)
g_evt_Numeracion_Changed();
};
btn_Listado.CheckedChanged += delegate
{
if (g_evt_Listado_Changed != null)
g_evt_Listado_Changed();
};
btn_Justificado_Izquierda.CheckedChanged += delegate
{
if (g_evt_JustificadoIzquierda_Changed != null)
g_evt_JustificadoIzquierda_Changed();
};
btn_Justificado_Centrado.CheckedChanged += delegate
{
if (g_evt_JustificadoCentro_Changed != null)
g_evt_JustificadoCentro_Changed();
};
btn_Justificado_Derecha.CheckedChanged += delegate
{
if (g_evt_JustificadoDerecha_Changed != null)
g_evt_JustificadoDerecha_Changed();
};
btn_Justificado_Completo.CheckedChanged += delegate
{
if (g_evt_JustificadoCompleto_Changed != null)
g_evt_JustificadoCompleto_Changed();
};
}
#endregion
private void Exferia_TextboxHTML_Load(object sender, EventArgs e)
{
timer.Start();
}
private void ParentForm_FormClosed(object sender, FormClosedEventArgs e)
{
timer.Stop();
ParentForm.FormClosed -= new FormClosedEventHandler(ParentForm_FormClosed);
}
#region Configurar Eventos del Navegador
private void Configurar_Eventos()
{
wbr_Principal.GotFocus += new EventHandler(wbr_Principal_GotFocus);
wbr_Principal.LostFocus += new EventHandler(wbr_Principal_LostFocus);
if (wbr_Principal.Version.Major >= 9)
wbr_Principal.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wbr_Principal_DocumentCompleted);
}
#region Foco
private void wbr_Principal_GotFocus(object sender, EventArgs e)
{
Poner_Foco();
if (!g_bol_SeAplicoEstilo)
{
IHTMLStyleSheet obj_IHTMLStyleSheet = g_obj_IHTMLDocument2.createStyleSheet("", 0);
obj_IHTMLStyleSheet.cssText = @"p { " +
"margin: 0; " +
"}";
}
//Para que salte el evento en el otro lado
Exferia_TextboxHTML_Evento_GotFocus?.Invoke(this, e);
}
private void Poner_Foco()
{
if (wbr_Principal.Document != null &&
wbr_Principal.Document.Body != null)
wbr_Principal.Document.Body.Focus();
}
private void wbr_Principal_LostFocus(object sender, EventArgs e)
{
//Para que salte el evento en el otro lado
Exferia_TextboxHTML_Evento_LostFocus?.Invoke(this, e);
}
#endregion
private void wbr_Principal_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (wbr_Principal.Document.Body != null)
{
wbr_Principal.Document.Body.SetAttribute("contentEditable", "true");
}
}
#endregion
#region Configurar Navegador
private void Configurar_Navegador()
{
wbr_Principal.DocumentText =
"<html>" +
"<head>"+
"</head>" +
"<body>" +
"</body>" +
"</html>";
g_obj_IHTMLDocument2 = wbr_Principal.Document.DomDocument as IHTMLDocument2;
g_obj_IHTMLDocument2.designMode = "On";
}
#endregion
#region Configurar Timer
private void Configurar_Timer()
{
timer.Interval = 200;
timer.Tick += new EventHandler(timer_Pulsacion);
}
#endregion
#region Configurar Nombre de Fuentes
/// <summary>
/// Completa el cuadro combinado de fuentes y autocompleta los controladores.
/// Agregue un controlador de texto modificado al cuadro combinado de fuente para manejar nuevas selecciones de fuente.
/// </summary>
private void Configurar_Fuente_Nombres()
{
AutoCompleteStringCollection obj_AutoCompleteStringCollection_Fuentes = new AutoCompleteStringCollection();
foreach (FontFamily obj_FontFamily in FontFamily.Families)
{
cbo_Fuente_Nombre.Items.Add(obj_FontFamily.Name);
obj_AutoCompleteStringCollection_Fuentes.Add(obj_FontFamily.Name);
}
cbo_Fuente_Nombre.Leave += new EventHandler(cbo_Fuente_Nombre_TextChanged);
cbo_Fuente_Nombre.AutoCompleteMode = AutoCompleteMode.Suggest;
cbo_Fuente_Nombre.AutoCompleteSource = AutoCompleteSource.CustomSource;
cbo_Fuente_Nombre.AutoCompleteCustomSource = obj_AutoCompleteStringCollection_Fuentes;
}
#endregion
#region Configurar Tamaño de Fuentes
private void Configurar_Fuente_Dimension()
{
for (int int_Contador = 1; int_Contador <= 7; int_Contador++)
{
cbo_Fuente_Dimension.Items.Add(int_Contador.ToString());
}
cbo_Fuente_Dimension.TextChanged += new EventHandler(cbo_Fuente_Dimension_TextChanged);
cbo_Fuente_Dimension.KeyPress += new KeyPressEventHandler(cbo_Fuente_Dimension_KeyPress);
}
#endregion
#region Fuentes
private void cbo_Fuente_Nombre_TextChanged(object sender, EventArgs e)
{
if (g_bol_Actualizando_NombreFuente) return;
FontFamily ff;
try
{
ff = new FontFamily(cbo_Fuente_Nombre.Text);
}
catch (Exception)
{
g_bol_Actualizando_NombreFuente = true;
cbo_Fuente_Nombre.Text = FontName.GetName(0);
g_bol_Actualizando_NombreFuente = false;
return;
}
FontName = ff;
}
[Browsable(false)]
public FontFamily FontName
{
get
{
if (ReadyState != ReadyState.Complete)
return null;
string str_Fuente = g_obj_IHTMLDocument2.queryCommandValue("FontName") as string;
if (str_Fuente == null) return null;
return new FontFamily(str_Fuente);
}
set
{
if (value != null)
wbr_Principal.Document.ExecCommand("FontName", false, value.Name);
}
}
/// <summary>
/// Actualizar el cuadro combinado de fuente.
/// Establece un indicador para indicar que el cuadro combinado se está actualizando, y debería
/// no actualiza la selección del editor.
/// </summary>
private void Actualizar_Combo_FuenteNombre()
{
if (!cbo_Fuente_Nombre.Focused)
{
FontFamily fam = FontName;
if (fam != null)
{
string fontname = fam.Name;
if (fontname != cbo_Fuente_Nombre.Text)
{
g_bol_Actualizando_NombreFuente = true;
cbo_Fuente_Nombre.Text = fontname;
if (g_evt_HtmlFuenteNombre_Changed != null)
g_evt_HtmlFuenteNombre_Changed();
g_bol_Actualizando_NombreFuente = false;
}
}
}
}
[Browsable(false)]
public FontSize FontSize
{
get
{
if (ReadyState != ReadyState.Complete)
return FontSize.NA;
string str_Fuente_Dimension = g_obj_IHTMLDocument2.queryCommandValue("FontSize").ToString();
switch (str_Fuente_Dimension)
{
case "1":
return FontSize.One;
case "2":
return FontSize.Two;
case "3":
return FontSize.Three;
case "4":
return FontSize.Four;
case "5":
return FontSize.Five;
case "6":
return FontSize.Six;
case "7":
return FontSize.Seven;
default:
return FontSize.NA;
}
}
set
{
int sz;
switch (value)
{
case FontSize.One:
sz = 1;
break;
case FontSize.Two:
sz = 2;
break;
case FontSize.Three:
sz = 3;
break;
case FontSize.Four:
sz = 4;
break;
case FontSize.Five:
sz = 5;
break;
case FontSize.Six:
sz = 6;
break;
case FontSize.Seven:
sz = 7;
break;
default:
sz = 7;
break;
}
wbr_Principal.Document.ExecCommand("FontSize", false, sz.ToString());
}
}
/// <summary>
/// Actualizar el cuadro combinado de tamaño de fuente.
/// Establece un indicador para indicar que el cuadro combinado se está actualizando, y debería
/// no actualiza la selección del editor.
/// </summary>
private void Actualizar_Combo_FuenteDimension()
{
if (!cbo_Fuente_Dimension.Focused)
{
int foo;
switch (FontSize)
{
case FontSize.One:
foo = 1;
break;
case FontSize.Two:
foo = 2;
break;
case FontSize.Three:
foo = 3;
break;
case FontSize.Four:
foo = 4;
break;
case FontSize.Five:
foo = 5;
break;
case FontSize.Six:
foo = 6;
break;
case FontSize.Seven:
foo = 7;
break;
case FontSize.NA:
foo = 0;
break;
default:
foo = 7;
break;
}
string str_Fuente_Dimension = Convert.ToString(foo);
if (str_Fuente_Dimension != cbo_Fuente_Dimension.Text)
{
g_bol_Actualizando_DimensionFuente = true;
cbo_Fuente_Dimension.Text = str_Fuente_Dimension;
if (g_evt_HtmlFuenteDimension_Changed != null)
g_evt_HtmlFuenteDimension_Changed();
g_bol_Actualizando_DimensionFuente = false;
}
}
}
private void cbo_Fuente_Dimension_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsNumber(e.KeyChar))
{
e.Handled = true;
if (e.KeyChar <= '7' && e.KeyChar > '0')
cbo_Fuente_Dimension.Text = e.KeyChar.ToString();
}
else if (!Char.IsControl(e.KeyChar))
{
e.Handled = true;
}
}
private void cbo_Fuente_Dimension_TextChanged(object sender, EventArgs e)
{
if (g_bol_Actualizando_DimensionFuente) return;
switch (cbo_Fuente_Dimension.Text.Trim())
{
case "1":
FontSize = FontSize.One;
break;
case "2":
FontSize = FontSize.Two;
break;
case "3":
FontSize = FontSize.Three;
break;
case "4":
FontSize = FontSize.Four;
break;
case "5":
FontSize = FontSize.Five;
break;
case "6":
FontSize = FontSize.Six;
break;
case "7":
FontSize = FontSize.Seven;
break;
default:
FontSize = FontSize.Seven;
break;
}
}
#endregion
#region Pulsacion del Timer
private void timer_Pulsacion(object sender, EventArgs e)
{
if (!g_bol_Timer_Iniciado)
{
ParentForm.FormClosed += new FormClosedEventHandler(ParentForm_FormClosed);
g_bol_Timer_Iniciado = true;
g_dtt_UltimaEntrada = DateTime.Now;
}
// don't process until browser is in ready state.
if (ReadyState != ReadyState.Complete)
return;
SetupKeyListener();
//Checkear Botones
btn_Negrita.Checked = Esta_En_Negrita();
btn_Italica.Checked = Esta_En_Italica();
btn_Subrayado.Checked = Esta_Subrayado();
btn_Justificado_Izquierda.Checked = Esta_Justificado_Izquierda();
btn_Justificado_Centrado.Checked = Esta_Justificado_Centro();
btn_Justificado_Derecha.Checked = Esta_Justificado_Derecha();
btn_Justificado_Completo.Checked = Esta_Justificado_Completo();
btn_Numeracion.Checked = Esta_En_Numeracion();
btn_Listado.Checked = Esta_En_Listado();
Actualizar_Combo_FuenteNombre();
Actualizar_Combo_FuenteDimension();
if (g_evt_Tick != null)
g_evt_Tick();
}
#endregion
/// <summary>
/// Obtenga el estado listo del componente interno del navegador.
/// </summary>
public ReadyState ReadyState
{
get
{
switch (g_obj_IHTMLDocument2.readyState.ToLower())
{
case "uninitialized":
return ReadyState.Uninitialized;
case "loading":
return ReadyState.Loading;
case "loaded":
return ReadyState.Loaded;
case "interactive":
return ReadyState.Interactive;
case "complete":
return ReadyState.Complete;
default:
return ReadyState.Uninitialized;
}
}
}
/// <summary>
/// Configurar un oyente clave en el cuerpo una vez.
/// El oyente clave verifica las pulsaciones de tecla y las tomas específicas
/// acción especial en ciertos casos.
/// </summary>
private void SetupKeyListener()
{
if (!g_bol_Configuracion)
{
wbr_Principal.Document.Body.KeyDown += new HtmlElementEventHandler(Body_KeyDown);
g_bol_Configuracion = true;
}
}
/// <summary>
/// Si el usuario pulsa la tecla Intro, y el evento se disparará (EnterKeyEvent),
/// y los consumidores de este evento pueden cancelar la proyección del
/// tecla enter cancelando el evento.
/// Esto es útil si su aplicación desea tomar alguna acción
/// cuando se presiona la tecla enter, como un envío a un servicio web.
/// </summary>
private void Body_KeyDown(object sender, HtmlElementEventArgs e)
{
if (e.KeyPressedCode == 13 && !e.ShiftKeyPressed)
{
// handle enter code cancellation
bool cancel = false;
if (g_evt_EnterKeyEvent != null)
{
EnterKeyEventArgs args = new EnterKeyEventArgs();
g_evt_EnterKeyEvent(this, args);
cancel = args.Cancel;
}
e.ReturnValue = !cancel;
}
}
#region Esta el Texto ...
public bool Esta_En_Negrita()
{
return g_obj_IHTMLDocument2.queryCommandState("Bold");
}
public bool Esta_En_Italica()
{
return g_obj_IHTMLDocument2.queryCommandState("Italic");
}
public bool Esta_Subrayado()
{
return g_obj_IHTMLDocument2.queryCommandState("Underline");
}
public bool Esta_Justificado_Izquierda()
{
return g_obj_IHTMLDocument2.queryCommandState("JustifyLeft");
}
public bool Esta_Justificado_Centro()
{
return g_obj_IHTMLDocument2.queryCommandState("JustifyCenter");
}
public bool Esta_Justificado_Derecha()
{
return g_obj_IHTMLDocument2.queryCommandState("JustifyRight");
}
public bool Esta_Justificado_Completo()
{
return g_obj_IHTMLDocument2.queryCommandState("JustifyFull");
}
public bool Esta_En_Numeracion()
{
return g_obj_IHTMLDocument2.queryCommandState("InsertOrderedList");
}
public bool Esta_En_Listado()
{
return g_obj_IHTMLDocument2.queryCommandState("InsertUnorderedList");
}
#endregion
#region Botones
private void btn_Negrita_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("Bold", false, null);
}
private void btn_Italica_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("Italic", false, null);
}
private void btn_Subrayado_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("Underline", false, null);
}
private void btn_ColorLetra_Click(object sender, EventArgs e)
{
Color clr_Color_Letra = EditorForeColor;
if (ShowColorDialog(ref clr_Color_Letra))
EditorForeColor = clr_Color_Letra;
}
private void btn_ColorFondoLetra_Click(object sender, EventArgs e)
{
Color clr_Color_Fondo = EditorBackColor;
if (ShowColorDialog(ref clr_Color_Fondo))
EditorBackColor = clr_Color_Fondo;
}
private void btn_Justificado_Izquierda_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("JustifyLeft", false, null);
}
private void btn_Justificado_Centrado_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("JustifyCenter", false, null);
}
private void btn_Justificado_Derecha_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("JustifyRight", false, null);
}
private void btn_Justificado_Completo_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("JustifyFull", false, null);
}
private void btn_Numeracion_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("InsertOrderedList", false, null);
}
private void btn_Listado_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("InsertUnorderedList", false, null);
}
private void btn_Disminuir_Identacion_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("Outdent", false, null);
}
private void btn_Aumentar_Identacion_Click(object sender, EventArgs e)
{
wbr_Principal.Document.ExecCommand("Indent", false, null);
}
#endregion
#region Colores
/// <summary>
/// Obtenga / Establezca el color de primer plano (texto) del editor para la selección actual.
/// </summary>
[Browsable(false)]
public Color EditorForeColor
{
get
{
if (ReadyState != ReadyState.Complete)
return Color.Black;
return ConvertToColor(g_obj_IHTMLDocument2.queryCommandValue("ForeColor").ToString());
}
set
{
string colorstr =
string.Format("#{0:X2}{1:X2}{2:X2}", value.R, value.G, value.B);
wbr_Principal.Document.ExecCommand("ForeColor", false, colorstr);
}
}
/// <summary>
/// Obtenga / Establezca el color de fondo del editor para la selección actual.
/// </summary>
[Browsable(false)]
public Color EditorBackColor
{
get
{
if (ReadyState != ReadyState.Complete)
return Color.White;
return ConvertToColor(g_obj_IHTMLDocument2.queryCommandValue("BackColor").ToString());
}
set
{
string colorstr =
string.Format("#{0:X2}{1:X2}{2:X2}", value.R, value.G, value.B);
wbr_Principal.Document.ExecCommand("BackColor", false, colorstr);
}
}
/// <summary>
/// Convierta el formato entero personalizado (B G R) en un objeto de color.
/// </summary>
private static Color ConvertToColor(string _str_Color)
{
int int_red, int_green, int_blue;
// sometimes clrs is HEX organized as (RED)(GREEN)(BLUE)
if (_str_Color.StartsWith("#"))
{
int clrn = Convert.ToInt32(_str_Color.Substring(1), 16);
int_red = (clrn >> 16) & 255;
int_green = (clrn >> 8) & 255;
int_blue = clrn & 255;
}
else // otherwise clrs is DECIMAL organized as (BlUE)(GREEN)(RED)
{
int clrn = Convert.ToInt32(_str_Color);
int_red = clrn & 255;
int_green = (clrn >> 8) & 255;
int_blue = (clrn >> 16) & 255;
}
Color clr_Color_Final = Color.FromArgb(int_red, int_green, int_blue);
return clr_Color_Final;
}
private bool ShowColorDialog(ref Color _clr_Color)
{
bool selected;
using (ColorDialog dlg = new ColorDialog())
{
dlg.SolidColorOnly = true;
dlg.AllowFullOpen = false;
dlg.AnyColor = false;
dlg.FullOpen = false;
dlg.CustomColors = null;
dlg.Color = _clr_Color;
if (dlg.ShowDialog(this) == DialogResult.OK)
{
selected = true;
_clr_Color = dlg.Color;
}
else
{
selected = false;
}
}
return selected;
}
#endregion
}
public enum FontSize
{
One,
Two,
Three,
Four,
Five,
Six,
Seven,
NA
}
public enum ReadyState
{
Uninitialized,
Loading,
Loaded,
Interactive,
Complete
}
}