实例介绍
【实例简介】
【实例截图】
【核心代码】
using System; using System.ComponentModel; using System.Configuration; using System.Drawing; using System.Globalization; #if VS2010 using System.Linq; #endif using System.Text; using System.Text.RegularExpressions; using System.Runtime.InteropServices; using System.IO; using System.Threading; using System.Windows.Forms; using WinHtmlEditor.Properties; using System.Diagnostics; using mshtmlTextRange = mshtml.IHTMLTxtRange; using mshtmlSelection = mshtml.IHTMLSelectionObject; using mshtmlDocument = mshtml.HTMLDocument; using mshtmlBody = mshtml.HTMLBody; using mshtmlControlRange = mshtml.IHTMLControlRange; using mshtmlElement = mshtml.IHTMLElement; using mshtmlEventObject = mshtml.IHTMLEventObj; using mshtmlElementCollection = mshtml.IHTMLElementCollection; using mshtmlAnchorElement = mshtml.IHTMLAnchorElement; using mshtmlDomNode = mshtml.IHTMLDOMNode; using mshtmlStyle = mshtml.IHTMLStyle; using mshtmlIHTMLDocument2 = mshtml.IHTMLDocument2; using mshtmlTable = mshtml.IHTMLTable; using mshtmlTableCaption = mshtml.IHTMLTableCaption; using mshtmlTableRow = mshtml.IHTMLTableRow; using Pavonis.COM; using Pavonis.COM.IOleCommandTarget; using System.IO.Compression; namespace WinHtmlEditor { [Docking(DockingBehavior.Ask), ComVisible(true), ClassInterface(ClassInterfaceType.AutoDispatch), ToolboxBitmap(typeof(HtmlEditor), "Resources.HTML.bmp")] public sealed partial class HtmlEditor : UserControl { /// <summary> /// Public event that is raised if an internal processing exception is found /// </summary> [Category("Exception"), Description("An Internal Processing Exception was encountered")] public event HtmlExceptionEventHandler HtmlException; /// <summary> /// Public event that is raised if navigation event is captured /// </summary> [Category("Navigation"), Description("A Navigation Event was encountered")] public event HtmlNavigationEventHandler HtmlNavigation; // browser html constan expressions private const string BLANK_HTML_PAGE = "about:blank"; // define the tags being used by the application private const string ANCHOR_TAG = "A"; private const string TABLE_TAG = "TABLE"; private const string SELECT_TYPE_TEXT = "text"; private const string SELECT_TYPE_CONTROL = "control"; private const string SELECT_TYPE_NONE = "none"; // define commands for mshtml execution execution private const string HTML_COMMAND_FONTNAME = "FontName"; private const string HTML_COMMAND_FONTSIZE = "FontSize"; private const string HTML_COMMAND_PRINT = "Print"; private const string HTML_COMMAND_COPY = "Copy"; private const string HTML_COMMAND_PASTE = "Paste"; private const string HTML_COMMAND_CUT = "Cut"; private const string HTML_COMMAND_DELETE = "Delete"; private const string HTML_COMMAND_UNDO = "Undo"; private const string HTML_COMMAND_REDO = "Redo"; private const string HTML_COMMAND_REMOVE_FORMAT = "RemoveFormat"; private const string HTML_COMMAND_JUSTIFY_CENTER = "JustifyCenter"; private const string HTML_COMMAND_JUSTIFY_FULL = "JustifyFull"; private const string HTML_COMMAND_JUSTIFY_LEFT = "JustifyLeft"; private const string HTML_COMMAND_JUSTIFY_RIGHT = "JustifyRight"; private const string HTML_COMMAND_UNDERLINE = "Underline"; private const string HTML_COMMAND_ITALIC = "Italic"; private const string HTML_COMMAND_BOLD = "Bold"; private const string HTML_COMMAND_BACK_COLOR = "BackColor"; private const string HTML_COMMAND_FORE_COLOR = "ForeColor"; private const string HTML_COMMAND_STRIKE_THROUGH = "StrikeThrough"; private const string HTML_COMMAND_CREATE_LINK = "CreateLink"; private const string HTML_COMMAND_UNLINK = "Unlink"; private const string HTML_COMMAND_INSERT_HORIZONTAL_RULE = "InsertHorizontalRule"; private const string HTML_COMMAND_INSERT_IMAGE = "InsertImage"; private const string HTML_COMMAND_OUTDENT = "Outdent"; private const string HTML_COMMAND_INDENT = "Indent"; private const string HTML_COMMAND_INSERT_UNORDERED_LIST = "InsertUnorderedList"; private const string HTML_COMMAND_INSERT_ORDERED_LIST = "InsertOrderedList"; private const string HTML_COMMAND_SUPERSCRIPT = "Superscript"; private const string HTML_COMMAND_SUBSCRIPT = "Subscript"; private const string HTML_COMMAND_SELECT_ALL = "SelectAll"; // internal command constants private const string INTERNAL_COMMAND_NEW = "New"; private const string INTERNAL_COMMAND_OPEN = "Open"; private const string INTERNAL_COMMAND_PRINT = "Print"; private const string INTERNAL_COMMAND_SAVE = "Save"; private const string INTERNAL_COMMAND_PREVIEW = "Preview"; private const string INTERNAL_COMMAND_SHOWHTML = "ShowHTML"; private const string INTERNAL_COMMAND_COPY = "Copy"; private const string INTERNAL_COMMAND_PASTE = "Paste"; private const string INTERNAL_COMMAND_CUT = "Cut"; private const string INTERNAL_COMMAND_DELETE = "Delete"; private const string INTERNAL_COMMAND_UNDO = "Undo"; private const string INTERNAL_COMMAND_REDO = "Redo"; private const string INTERNAL_COMMAND_FIND = "Find"; private const string INTERNAL_COMMAND_REMOVE_FORMAT = "RemoveFormat"; private const string INTERNAL_COMMAND_JUSTIFYCENTER = "JustifyCenter"; private const string INTERNAL_COMMAND_JUSTIFYFULL = "JustifyFull"; private const string INTERNAL_COMMAND_JUSTIFYLEFT = "JustifyLeft"; private const string INTERNAL_COMMAND_JUSTIFYRIGHT = "JustifyRight"; private const string INTERNAL_COMMAND_UNDERLINE = "Underline"; private const string INTERNAL_COMMAND_ITALIC = "Italic"; private const string INTERNAL_COMMAND_BOLD = "Bold"; private const string INTERNAL_COMMAND_BACKCOLOR = "BackColor"; private const string INTERNAL_COMMAND_FORECOLOR = "ForeColor"; private const string INTERNAL_COMMAND_STRIKETHROUGH = "StrikeThrough"; private const string INTERNAL_COMMAND_CREATELINK = "CreateLink"; private const string INTERNAL_COMMAND_UNLINK = "Unlink"; private const string INTERNAL_COMMAND_INSERTTABLE = "InsertTable"; private const string INTERNAL_COMMAND_TABLEPROPERTIES = "TableModify"; private const string INTERNAL_COMMAND_TABLEINSERTROW = "TableInsertRow"; private const string INTERNAL_COMMAND_TABLEDELETEROW = "TableDeleteRow"; private const string INTERNAL_COMMAND_INSERTIMAGE = "InsertImage"; private const string INTERNAL_COMMAND_INSERTHORIZONTALRULE = "InsertHorizontalRule"; private const string INTERNAL_COMMAND_OUTDENT = "Outdent"; private const string INTERNAL_COMMAND_INDENT = "Indent"; private const string INTERNAL_COMMAND_INSERTUNORDEREDLIST = "InsertUnorderedList"; private const string INTERNAL_COMMAND_INSERTORDEREDLIST = "InsertOrderedList"; private const string INTERNAL_COMMAND_SUPERSCRIPT = "Superscript"; private const string INTERNAL_COMMAND_SUBSCRIPT = "Subscript"; private const string INTERNAL_COMMAND_SELECTALL = "SelectAll"; private const string INTERNAL_COMMAND_WORDCOUNT = "WordCount"; private const string INTERNAL_COMMAND_INSERTDATE = "InsertDate"; private const string INTERNAL_COMMAND_INSERTTIME = "InsertTime"; private const string INTERNAL_COMMAND_CLEARWORD = "ClearWord"; private const string INTERNAL_COMMAND_AUTOLAYOUT = "AutoLayout"; private const string INTERNAL_COMMAND_ABOUT = "About"; // constants for displaying the HTML dialog private const string CONTENT_EDITABLE_INHERIT = "inherit"; private const string HTML_TITLE_EDIT = "Edit Html"; private const string DEFAULT_HTML_TEXT = ""; private const string BODY_PARSE_PRE_EXPRESSION = @"(<body).*?(</body)"; private const string BODY_PARSE_EXPRESSION = @"(?<bodyOpen>(<body).*?>)(?<innerBody>.*?)(?<bodyClose>(</body\s*>))"; private const string BODY_DEFAULT_TAG = @"<Body></Body>"; private const string BODY_TAG_PARSE_MATCH = @"${bodyOpen}${bodyClose}"; private const string BODY_INNER_PARSE_MATCH = @"${innerBody}"; // browser constants and commands private object EMPTY_PARAMETER; // internal body property values private bool _readOnly; private HtmlFontProperty _bodyFont; private Color _bodyBackColor; private Color _bodyForeColor; private int[] _customColors; private readonly NavigateActionOption _navigateWindow; private DisplayScrollBarOption _scrollBars; private bool _autoWordWrap; // default values used to reset values private readonly Color _defaultBodyBackColor; private readonly Color _defaultBodyForeColor; private readonly HtmlFontProperty _defaultFont; // internal property values private string _bodyText; private string _bodyHtml; private string _bodyUrl; private bool _toolbarVisible; private bool _statusbarVisible; private bool _wbVisible; // document and body elements private mshtmlDocument document; private mshtmlIHTMLDocument2 _doc; // find and replace internal text range private mshtmlTextRange _findRange; private volatile bool rebaseUrlsNeeded; private volatile bool loading; private volatile bool codeNavigate; private mshtmlBody body; private bool _updatingFontName; private bool _updatingFontSize; public class EnterKeyEventArgs : EventArgs { public EnterKeyEventArgs() { Cancel = false; } public bool Cancel { get; set; } } public event EventHandler<EnterKeyEventArgs> EnterKeyEvent; public HtmlEditor() { InitializeComponent(); // define the default values // browser constants and commands EMPTY_PARAMETER = System.Reflection.Missing.Value; // default values used to reset values _defaultBodyBackColor = Color.White; _defaultBodyForeColor = Color.Black; _defaultFont = new HtmlFontProperty(Font); _navigateWindow = NavigateActionOption.Default; _scrollBars = DisplayScrollBarOption.Auto; _autoWordWrap = true; _toolbarVisible = true; _statusbarVisible = true; _wbVisible = true; _bodyText = DEFAULT_HTML_TEXT; _bodyHtml = DEFAULT_HTML_TEXT; _bodyBackColor = _defaultBodyBackColor; _bodyForeColor = _defaultBodyForeColor; _bodyFont = _defaultFont; // load the blank Html page to load the MsHtml object model BrowserCodeNavigate(BLANK_HTML_PAGE); // after load ensure document marked as editable ReadOnly = _readOnly; ScrollBars = _scrollBars; SetupComboFontSize(); SynchFont(string.Empty); } /// <summary> /// Method used to navigate to the required page /// Call made sync using a loading variable /// </summary> private void BrowserCodeNavigate(string url) { // once navigated to the href page wait until successful // need to do this to ensure properties are all correctly set codeNavigate = true; loading = true; // perform the navigation wb.Navigate(url); // wait for the navigate to complete using the loading variable // DoEvents needs to be called to enable the DocumentComplete to execute while (loading) { Application.DoEvents(); Thread.Sleep(0); } } //BrowserCodeNavigate [Description("The Inner HTML of the contents"), Category("Textual")] public string BodyInnerHTML { get { _bodyText = body.innerText; _bodyHtml = body.innerHTML; return _bodyHtml; } set { try { // clear the defined body url _bodyUrl = string.Empty; if (value.IsNull()) value = string.Empty; // set the body property body.innerHTML = value; // set the body text and html _bodyText = body.innerText; _bodyHtml = body.innerHTML; // if needed rebase urls RebaseAnchorUrl(); } catch (Exception ex) { throw new HtmlEditorException("Inner Html for the body cannot be set.", "SetInnerHtml", ex); } } } /// <summary> /// Method to remove references to about:blank from the anchors /// </summary> private void RebaseAnchorUrl() { if (rebaseUrlsNeeded) { // review the anchors and remove any references to about:blank mshtmlElementCollection anchors = body.getElementsByTagName(ANCHOR_TAG); foreach (mshtmlElement element in anchors) { try { var anchor = (mshtmlAnchorElement)element; string href = anchor.href; // see if href need updating if (!href.IsNull() && Regex.IsMatch(href, BLANK_HTML_PAGE, RegexOptions.IgnoreCase)) { anchor.href = href.Replace(BLANK_HTML_PAGE, string.Empty); } } catch (Exception) { // ignore any errors } } } } //RebaseAnchorUrl /// <summary> /// Property defining the base text for the body /// The HTML value can be used at runtime /// </summary> [Category("Textual"), Description("Set the initial Body Text")] [DefaultValue(DEFAULT_HTML_TEXT)] public string BodyInnerText { get { _bodyText = body.innerText; _bodyHtml = body.innerHTML; return _bodyText; } set { try { // clear the defined body url _bodyUrl = string.Empty; if (value.IsNull()) value = string.Empty; // set the body property body.innerText = value; // set the body text and html _bodyText = body.innerText; _bodyHtml = body.innerHTML; } catch (Exception ex) { throw new HtmlEditorException("Inner Text for the body cannot be set.", "SetInnerText", ex); } } } //BodyInnerText /// <summary> /// Property returning any Url that was used to load the current document /// </summary> [Category("Textual"), Description("Url used to load the Document")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] public string DocumentUrl { get { //return document.baseUrl; return _bodyUrl; } } [Category("Appearance"), DefaultValue("false"), Description("设置或获取一个值,决定按下回车键的时候是插入BR还是P")] public bool EnterToBR { get; set; } /// <summary> /// Property defining the editable status of the text /// </summary> [Category("RuntimeDisplay"), Description("Marks the content as ReadOnly")] [DefaultValue(false)] public bool ReadOnly { get { return _readOnly; } set { _readOnly = value; // define the document editable property body.contentEditable = (!_readOnly).ToString(); // define the menu bar state tsTopToolBar.Enabled = (!_readOnly); // define whether the IE cntext menu should be shown wb.IsWebBrowserContextMenuEnabled = _readOnly; } } //ReadOnly /// <summary> /// Property defining the body tag of the html /// On set operation the body attributes are redefined /// </summary> [Category("Textual"), Description("Complete Document including Body Tag")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] public string BodyHtml { get { // set the read only property before return body.contentEditable = CONTENT_EDITABLE_INHERIT; string html = _doc.body.outerHTML.Trim(); ReadOnly = _readOnly; return html; } set { // clear the defined body url _bodyUrl = string.Empty; // define some local working variables string bodyElement = string.Empty; string innerHtml = string.Empty; try { // ensure have body open and close tags if (Regex.IsMatch(value, BODY_PARSE_PRE_EXPRESSION, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline)) { // define a regular expression for the Html Body parsing and obtain the match expression var expression = new Regex(BODY_PARSE_EXPRESSION, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.ExplicitCapture); var match = expression.Match(value); // see if a match was found if (match.Success) { // extract the body tag and the inner html bodyElement = match.Result(BODY_TAG_PARSE_MATCH); innerHtml = match.Result(BODY_INNER_PARSE_MATCH); // remove whitespaces from the body and inner html tags bodyElement = bodyElement.Trim(); innerHtml = innerHtml.Trim(); } } // ensure body was set if (bodyElement == string.Empty) { // assume the Html given is an inner html with no body bodyElement = BODY_DEFAULT_TAG; innerHtml = value.Trim(); } // first navigate to a blank page to reset the html header BrowserCodeNavigate(BLANK_HTML_PAGE); // replace the body tag with the one passed in var oldBodyNode = (mshtmlDomNode)document.body; var newBodyNode = (mshtmlDomNode)document.createElement(bodyElement); oldBodyNode.replaceNode(newBodyNode); // define the new inner html and body objects body = (mshtmlBody)document.body; body.innerHTML = innerHtml; // now all successfully loaded need to review the body attributes _bodyText = body.innerText; _bodyHtml = body.innerHTML; // set and define the appropriate properties // this will set the appropriate read only property DefineBodyAttributes(); // if needed rebase urls RebaseAnchorUrl(); } catch (Exception ex) { throw new HtmlEditorException("Outer Html for the body cannot be set.", "SetBodyHtml", ex); } } } //BodyHtml /// <summary> /// Defines all the body attributes once a document has been loaded /// </summary> private void DefineBodyAttributes() { // define the body colors based on the new body html _bodyBackColor = GeneralUtil.IsNull(body.bgColor) ? _defaultBodyBackColor : ColorTranslator.FromHtml((string)body.bgColor); _bodyForeColor = GeneralUtil.IsNull(body.text) ? _defaultBodyForeColor : ColorTranslator.FromHtml((string)body.text); // define the font object based on current font of new document // deafult used unless a style on the body modifies the value mshtmlStyle bodyStyle = body.style; if (!bodyStyle.IsNull()) { string fontName = _bodyFont.Name; HtmlFontSize fontSize = _bodyFont.Size; bool fontBold = _bodyFont.Bold; bool fontItalic = _bodyFont.Italic; // define the font name if defined in the style if (!bodyStyle.fontFamily.IsNull()) fontName = bodyStyle.fontFamily; if (!GeneralUtil.IsNull(bodyStyle.fontSize)) fontSize = HtmlFontConversion.StyleSizeToHtml(bodyStyle.fontSize.ToString()); if (!bodyStyle.fontWeight.IsNull()) fontBold = HtmlFontConversion.IsStyleBold(bodyStyle.fontWeight); if (!bodyStyle.fontStyle.IsNull()) fontItalic = HtmlFontConversion.IsStyleItalic(bodyStyle.fontStyle); bool fontUnderline = bodyStyle.textDecorationUnderline; // define the new font object and set the property _bodyFont = new HtmlFontProperty(fontName, fontSize, fontBold, fontItalic, fontUnderline); BodyFont = _bodyFont; } // define the content based on the current value ReadOnly = _readOnly; ScrollBars = _scrollBars; AutoWordWrap = _autoWordWrap; } //DefineBodyAttributes /// <summary> /// Property defining whether scroll bars should be displayed /// </summary> [Category("RuntimeDisplay"), Description("Controls the Display of Scrolls Bars")] [DefaultValue(DisplayScrollBarOption.Auto)] public DisplayScrollBarOption ScrollBars { get { return _scrollBars; } set { _scrollBars = value; // define the document scroll bar visibility body.scroll = _scrollBars.ToString(); } } //ScrollBars /// <summary> /// Property defining whether words will be auto wrapped /// </summary> [Category("RuntimeDisplay"), Description("Controls the auto wrapping of content")] [DefaultValue(true)] public bool AutoWordWrap { get { return _autoWordWrap; } set { _autoWordWrap = value; // define the document word wrap property body.noWrap = !_autoWordWrap; } } //AutoWordWrap /// <summary> /// Property for the base font to use for text editing /// Reset and Serialize values defined /// </summary> [Category("Textual"), Description("Defines the base Font object for the Body")] [RefreshProperties(RefreshProperties.All)] public HtmlFontProperty BodyFont { get { return _bodyFont; } set { // set the new value using the default if set to null _bodyFont = HtmlFontProperty.IsNotNull(value) ? value : _defaultFont; // set the font attributes based on any body styles mshtmlStyle bodyStyle = body.style; if (!bodyStyle.IsNull()) { if (HtmlFontProperty.IsEqual(_bodyFont, _defaultFont)) { // ensure no values are set in the Body style if (!bodyStyle.fontFamily.IsNull()) bodyStyle.fontFamily = string.Empty; if (!GeneralUtil.IsNull(bodyStyle.fontSize)) bodyStyle.fontSize = string.Empty; if (!bodyStyle.fontWeight.IsNull()) bodyStyle.fontWeight = string.Empty; } else { // set the body styles based on the defined value bodyStyle.fontFamily = _bodyFont.Name; bodyStyle.fontSize = HtmlFontConversion.HtmlFontSizeString(_bodyFont.Size); bodyStyle.fontWeight = HtmlFontConversion.HtmlFontBoldString(_bodyFont.Bold); } } } } //BodyFont public bool ShouldSerializeBodyFont() { return (HtmlFontProperty.IsNotEqual(_bodyFont, _defaultFont)); } //ShouldSerializeBodyFont public void ResetBodyFont() { this.BodyFont = _defaultFont; } //ResetBodyFont [Category("Appearance"), Description("Controls the visible of ToolBar"), DefaultValue("true")] public bool ShowToolBar { get { return _toolbarVisible; } set { _toolbarVisible = value; this.tsTopToolBar.Visible = _toolbarVisible; } } [Category("Appearance"), Description("Controls the visible of StatusStrip"), DefaultValue("true")] public bool ShowStatusBar { get { return _statusbarVisible; } set { _statusbarVisible = value; ssHtml.Visible = _statusbarVisible; } } [Category("Appearance"), Description("Controls the visible of html editor"), DefaultValue("true")] public bool ShowWb { get { return _wbVisible; } set { _wbVisible = value; wb.Visible = _wbVisible; } } [Category("Appearance"), Description("Controls the enable of shortcut key"), DefaultValue("true")] public bool WebBrowserShortcutsEnabled { get { return wb.WebBrowserShortcutsEnabled; } set { wb.WebBrowserShortcutsEnabled = value; } } #region public method #region Find and Replace Operations /// <summary> /// Dialog to allow the user to perform a find and replace /// </summary> public void FindReplacePrompt(bool findOrReplace) { // define a default value for the text to find mshtmlTextRange range = GetTextRange(); string initText = string.Empty; if (!range.IsNull()) { string findText = range.text; if (!findText.IsNull()) initText = findText.Trim(); } // prompt the user for the new href using (var dialog = new FindReplaceForm(initText, FindReplaceReset, FindFirst, FindNext, FindReplaceOne, FindReplaceAll, findOrReplace)) { DefineDialogProperties(dialog); dialog.ShowDialog(ParentForm); } } //FindReplacePrompt /// <summary> /// Method to reset the find and replace options to initialize a new search /// </summary> public void FindReplaceReset() { // reset the range being worked with _findRange = body.createTextRange(); document.selection.empty(); } //FindReplaceReset /// <summary> /// Method to find the first occurrence of the given text string /// Uses false case for the search options /// </summary> public bool FindFirst(string findText) { return FindFirst(findText, false, false); } //FindFirst /// <summary> /// Method to find the first occurrence of the given text string /// </summary> public bool FindFirst(string findText, bool matchWhole, bool matchCase) { // reset the text search range prior to making any calls FindReplaceReset(); // calls the Find Next once search has been initialized return FindNext(findText, matchWhole, matchCase); } //FindFirst /// <summary> /// Method to find the next occurrence of a given text string /// Assumes a previous search was made /// Uses false case for the search options /// </summary> public bool FindNext(string findText) { return FindNext(findText, false, false); } //FindNext /// <summary> /// Method to find the next occurrence of a given text string /// Assumes a previous search was made /// </summary> public bool FindNext(string findText, bool matchWhole, bool matchCase) { return (!FindText(findText, matchWhole, matchCase).IsNull()); } //FindNext /// <summary> /// Replace the first occurrence of the given string with the other /// Uses false case for the search options /// </summary> public bool FindReplaceOne(string findText, string replaceText) { return FindReplaceOne(findText, replaceText); } //FindReplaceOne /// <summary> /// Method to replace the first occurrence of the given string with the other /// </summary> public bool FindReplaceOne(string findText, string replaceText, bool matchWhole, bool matchCase) { // find the given text within the find range mshtmlTextRange replaceRange = FindText(findText, matchWhole, matchCase); if (!replaceRange.IsNull()) { // if text found perform a replace replaceRange.text = replaceText; replaceRange.select(); // replace made to return success return true; } // no replace was made so return false return false; } //FindReplaceOne /// <summary> /// Method to replace all the occurrence of the given string with the other /// Uses false case for the search options /// </summary> public int FindReplaceAll(string findText, string replaceText) { return FindReplaceAll(findText, replaceText, false, false); } //FindReplaceAll /// <summary> /// Method to replace all the occurrences of the given string with the other /// </summary> public int FindReplaceAll(string findText, string replaceText, bool matchWhole, bool matchCase) { int found = 0; mshtmlTextRange replaceRange; do { // find the given text within the find range replaceRange = FindText(findText, matchWhole, matchCase); // if found perform a replace if (!replaceRange.IsNull()) { replaceRange.text = replaceText; found ; } } while (!replaceRange.IsNull()); // return count of items repalced return found; } //FindReplaceAll /// <summary> /// Method to perform the actual find of the given text /// </summary> private mshtmlTextRange FindText(string findText, bool matchWhole, bool matchCase) { // define the search options int searchOptions = 0; if (matchWhole) searchOptions = searchOptions 2; if (matchCase) searchOptions = searchOptions 4; // perform the search operation if (!_findRange.text.IsNull() && _findRange.findText(findText, _findRange.text.Length, searchOptions)) { // select the found text within the document _findRange.select(); // limit the new find range to be from the newly found text var foundRange = (mshtmlTextRange)document.selection.createRange(); _findRange = body.createTextRange(); _findRange.setEndPoint("StartToEnd", foundRange); // text found so return this selection return foundRange; } // reset the find ranges FindReplaceReset(); // no text found so return null range return null; } //FindText #endregion /// <summary> /// 在当前工具栏上新加一个按钮 /// </summary> /// <param name="buttom">按钮</param> /// <returns></returns> public bool AddToobarButtom(ToolStripButton buttom) { buttom.DisplayStyle = ToolStripItemDisplayStyle.Image; return (tsTopToolBar.Items.Add(buttom) > 0); } /// <summary> /// 重置为空白页 /// </summary> public void Navigate() { NavigateToUrl("about:blank"); } /// <summary> /// 将指定的统一资源定位符 (URL) 处的文档加载到 System.Windows.Forms.WebBrowser 控件中,替换上一个文档。 /// </summary> /// <param name="url">指定的统一资源定位符 (URL)</param> public void NavigateToUrl(string url) { wb.Navigate(url); } /// <summary> /// Method to allow the user to load a document by navigation /// A new window can optionally be specified /// </summary> public void NavigateToUrl(string url, bool newWindow) { if (newWindow) { // open the Url in a new window wb.Navigate(url, true); } else { // if no new window required call the normal navigate method NavigateToUrl(url); } } //NavigateToUrl /// <summary> /// The currently selected text/controls will be replaced by the given HTML code. /// If nothing is selected, the HTML code is inserted at the cursor position /// </summary> /// <param name="sHtml"></param> public void PasteIntoSelection(string sHtml) { HTMLEditHelper.PasteIntoSelection(sHtml); } /// <summary> /// 统计Html编辑器内容的字数 /// </summary> /// <returns>字数</returns> public int WordCount() { Debug.Assert(wb.Document != null, "wb.Document != null"); Debug.Assert(wb.Document.Body != null, "wb.Document.Body != null"); #if VS2010 return wb.Document.Body.InnerText.IsNull() ? 0 : Regex.Split(wb.Document.Body.InnerText, @"\s"). Sum(si => Regex.Matches(si, @"[\u0000-\u00ff] ").Count si.Count(c => (int) c > 0x00FF)); #else if (wb.Document.Body.InnerText.IsNull()) return 0; var sec = Regex.Split(wb.Document.Body.InnerText, @"\s"); int count = 0; foreach (var si in sec) { int ci = Regex.Matches(si, @"[\u0000-\u00ff] ").Count; foreach (var c in si) if (c > 0x00FF) ci ; count = ci; } return count; #endif } /// <summary> /// Method to allow the user to view the html contents /// </summary> public void ShowHTML() { using (var dialog = new EditHtmlForm()) { dialog.HTML = BodyInnerHTML; dialog.ReadOnly = false; dialog.SetCaption(HTML_TITLE_EDIT); DefineDialogProperties(dialog); if (dialog.ShowDialog(ParentForm) == DialogResult.OK) { BodyInnerHTML = dialog.HTML; } } } /// <summary> /// Method to allow the user to preview the html page /// </summary> public void Preview() { bool isPreview = (body.contentEditable == "true"); for (int i = 0; i < tsTopToolBar.Items.Count; i ) { tsTopToolBar.Items[i].Enabled = !isPreview; } if(isPreview) { body.contentEditable = "false"; cmsHtml.Enabled = false; tsbPreview.Enabled = true; } else { cmsHtml.Enabled = true; body.contentEditable = "true"; } } /// <summary> /// New document /// </summary> public void New() { BodyHtml = ""; } //New /// <summary> /// Method to allow the user to persist the Html stream to a file /// </summary> public void Save() { using (var dialog = new SaveFileDialog { FileName = "", Filter = Resources.SaveFilter, Title = Resources.SaveTitle }) { if (dialog.ShowDialog() == DialogResult.OK) { var writer = new StreamWriter(dialog.FileName,false,Encoding.UTF8); writer.Write(BodyHtml); writer.Close(); } } } //New /// <summary> /// Method to allow the user to select a file and read the contents into the Html stream /// </summary> public void Open() { using (var dialog = new OpenFileDialog { FileName = "", Filter = Resources.OpenFilter, Title = Resources.OpenTitle }) { if (dialog.ShowDialog() == DialogResult.OK) { var reader = new StreamReader(dialog.FileName, Encoding.Default); BodyHtml = reader.ReadToEnd(); reader.Close(); } } } //Open /// <summary> /// Method to print the html text using the document print command /// Print preview is not supported /// </summary> public void Print() { ExecuteCommandDocument(HTML_COMMAND_PRINT); } //Print /// <summary> /// Method to copy the currently selected text to the clipboard /// </summary> public void Copy() { ExecuteCommandDocument(HTML_COMMAND_COPY); } //Copy /// <summary> /// Method to cut the currently selected text to the clipboard /// </summary> public void Cut() { ExecuteCommandDocument(HTML_COMMAND_CUT); } //Cut /// <summary> /// Method to paste the currently selected text from the clipboard /// </summary> public void Paste() { ExecuteCommandDocument(HTML_COMMAND_PASTE); } //Paste /// <summary> /// Method to delete the currently selected text from the screen /// </summary> public void Delete() { ExecuteCommandDocument(HTML_COMMAND_DELETE); } //Delete /// <summary> /// Method to undo former commands /// </summary> public void Undo() { ExecuteCommandDocument(HTML_COMMAND_UNDO); FormatSelectionChange(); } //Undo /// <summary> /// Method to redo former undo /// </summary> public void Redo() { ExecuteCommandDocument(HTML_COMMAND_REDO); FormatSelectionChange(); } //Redo /// <summary> /// Method to find string /// </summary> public void Find() { Focus(); SendKeys.SendWait("^f"); } /// <summary> /// Method to remove format /// </summary> public void RemoveFormat() { ExecuteCommandDocument(HTML_COMMAND_REMOVE_FORMAT); } //RemoveFormat /// <summary> /// Method to define the font justification as CENTER /// </summary> public void JustifyCenter() { ExecuteCommandRange(HTML_COMMAND_JUSTIFY_CENTER, null); FormatSelectionChange(); } //JustifyCenter /// <summary> /// Method to define the font justification as FULL /// </summary> public void JustifyFull() { ExecuteCommandRange(HTML_COMMAND_JUSTIFY_FULL, null); FormatSelectionChange(); } //JustifyFull /// <summary> /// Method to define the font justification as LEFT /// </summary> public void JustifyLeft() { ExecuteCommandRange(HTML_COMMAND_JUSTIFY_LEFT, null); FormatSelectionChange(); } //JustifyLeft /// <summary> /// Method to define the font justification as RIGHT /// </summary> public void JustifyRight() { ExecuteCommandRange(HTML_COMMAND_JUSTIFY_RIGHT, null); FormatSelectionChange(); } //JustifyRight /// <summary> /// Method using the document to toggle the selection with a underline tag /// </summary> public void Underline() { ExecuteCommandRange(HTML_COMMAND_UNDERLINE, null); FormatSelectionChange(); } //Underline /// <summary> /// Method using the document to toggle the selection with a italic tag /// </summary> public void Italic() { ExecuteCommandRange(HTML_COMMAND_ITALIC, null); FormatSelectionChange(); } //Italic /// <summary> /// Method using the document to toggle the selection with a bold tag /// </summary> public void Bold() { ExecuteCommandRange(HTML_COMMAND_BOLD, null); FormatSelectionChange(); } //Bold /// <summary> /// Method using the exec command to define the back color properties for the selected tag /// </summary> public void FormatBackColor(Color color) { // Use the COLOR object to set the property BackColor string colorHtml = color != Color.Empty ? ColorTranslator.ToHtml(color) : null; ExecuteCommandRange(HTML_COMMAND_BACK_COLOR, colorHtml); } /// <summary> /// Method to display the system color dialog /// Use use to set the selected text Back Color /// </summary> public void FormatBackColorPrompt() { // display the Color dialog and use the selected color to modify text using (var colorDialog = new ColorDialog()) { colorDialog.AnyColor = true; colorDialog.SolidColorOnly = true; colorDialog.AllowFullOpen = true; colorDialog.Color = GetBackColor(); colorDialog.CustomColors = _customColors; if (colorDialog.ShowDialog(ParentForm) == DialogResult.OK) { _customColors = colorDialog.CustomColors; FormatBackColor(colorDialog.Color); } } } //FormatBackColorPrompt /// <summary> /// Method using the exec command to define the color properties for the selected tag /// </summary> public void FormatFontColor(Color color) { // Use the COLOR object to set the property ForeColor string colorHtml = color != Color.Empty ? ColorTranslator.ToHtml(color) : null; ExecuteCommandRange(HTML_COMMAND_FORE_COLOR, colorHtml); } //FormatFontColor /// <summary> /// Method to display the system color dialog /// Use use to set the selected text Color /// </summary> public void FormatFontColorPrompt() { // display the Color dialog and use the selected color to modify text using (var colorDialog = new ColorDialog()) { colorDialog.AnyColor = true; colorDialog.SolidColorOnly = true; colorDialog.AllowFullOpen = true; colorDialog.Color = GetFontColor(); colorDialog.CustomColors = _customColors; if (colorDialog.ShowDialog(ParentForm) == DialogResult.OK) { _customColors = colorDialog.CustomColors; FormatFontColor(colorDialog.Color); } } } //FormatFontColorPrompt /// <summary> /// Method using the document to toggle the selection with a StrikeThrough tag /// </summary> public void StrikeThrough() { ExecuteCommandRange(HTML_COMMAND_STRIKE_THROUGH, null); FormatSelectionChange(); } //StrikeThrough /// <summary> /// Method using the document to create link /// </summary> public void CreateLink() { ExecuteCommandRange(HTML_COMMAND_CREATE_LINK, null); } //CreateLink /// <summary> /// Method using the document to remove link /// </summary> public void UnLink() { ExecuteCommandRange(HTML_COMMAND_UNLINK, null); FormatSelectionChange(); } //UnLink /// <summary> /// Method to insert a image and prompt a user for the link /// Calls the public InsertImage method /// </summary> public void InsertImage() { ExecuteCommandDocumentPrompt(HTML_COMMAND_INSERT_IMAGE); } //InsertImage /// <summary> /// /// </summary> public void AutoLayout() { if (!BodyInnerHTML.IsNullOrEmpty()) BodyInnerHTML = Regex.Replace(BodyInnerHTML, "(<P.*?>)[\\s]*( ){0,}[\\s]*", "$1 ", RegexOptions.IgnoreCase | RegexOptions.Multiline); } //AutoLayout /// <summary> /// Create a new focus method that ensure the body gets the focus /// Should be called when text processing command are called /// </summary> public new bool Focus() { // have the return value be the focus return from the user control bool focus = base.Focus(); // try to set the focus to the web browser try { wb.Focus(); if (!body.IsNull()) body.focus(); } catch (Exception) { // ignore errors } return focus; } //Focus #region Table Processing Operations /// <summary> /// Method to create a table class /// Insert method then works on this table /// </summary> public void TableInsert(HtmlTableProperty tableProperties) { // call the private insert table method with a null table entry ProcessTable(null, tableProperties); } //TableInsert /// <summary> /// Method to modify a tables properties /// Ensure a table is currently selected or insertion point is within a table /// </summary> public bool TableModify(HtmlTableProperty tableProperties) { // define the Html Table element mshtmlTable table = GetTableElement(); // if a table has been selected then process if (!table.IsNull()) { ProcessTable(table, tableProperties); return true; } return false; } //TableModify /// <summary> /// Method to present to the user the table properties dialog /// Uses all the default properties for the table based on an insert operation /// </summary> public void TableInsertPrompt() { // if user has selected a table create a reference var table = GetFirstControl() as mshtmlTable; ProcessTablePrompt(table); } //TableInsertPrompt /// <summary> /// Method to present to the user the table properties dialog /// Ensure a table is currently selected or insertion point is within a table /// </summary> public bool TableModifyPrompt() { // define the Html Table element mshtmlTable table = GetTableElement(); // if a table has been selected then process if (!table.IsNull()) { ProcessTablePrompt(table); return true; } return false; } //TableModifyPrompt /// <summary> /// Method to insert a new row into the table /// Based on the current user row and insertion after /// </summary> public void TableInsertRow() { // see if a table selected or insertion point inside a table mshtmlTable table; mshtmlTableRow row; GetTableElement(out table, out row); // process according to table being defined if (!table.IsNull() && !row.IsNull()) { try { // find the existing row the user is on and perform the insertion int index = row.rowIndex 1; var insertedRow = (mshtmlTableRow)table.insertRow(index); // add the new columns to the end of each row int numberCols = row.cells.length; for (int idxCol = 0; idxCol < numberCols; idxCol ) { insertedRow.insertCell(); } } catch (Exception ex) { throw new HtmlEditorException("Unable to insert a new Row", "TableinsertRow", ex); } } else { throw new HtmlEditorException("Row not currently selected within the table", "TableInsertRow"); } } //TableInsertRow /// <summary> /// Method to delete the currently selected row /// Operation based on the current user row location /// </summary> public void TableDeleteRow() { // see if a table selected or insertion point inside a table mshtmlTable table; mshtmlTableRow row; GetTableElement(out table, out row); // process according to table being defined if (!table.IsNull() && !row.IsNull()) { try { // find the existing row the user is on and perform the deletion int index = row.rowIndex; table.deleteRow(index); } catch (Exception ex) { throw new HtmlEditorException("Unable to delete the selected Row", "TableDeleteRow", ex); } } else { throw new HtmlEditorException("Row not currently selected within the table", "TableDeleteRow"); } } //TableDeleteRow /// <summary> /// Method to present to the user the table properties dialog /// Uses all the default properties for the table based on an insert operation /// </summary> private void ProcessTablePrompt(mshtmlTable table) { using (var dialog = new TablePropertyForm()) { // define the base set of table properties HtmlTableProperty tableProperties = GetTableProperties(table); // set the dialog properties dialog.TableProperties = tableProperties; DefineDialogProperties(dialog); // based on the user interaction perform the neccessary action if (dialog.ShowDialog(ParentForm) == DialogResult.OK) { tableProperties = dialog.TableProperties; if (table.IsNull()) TableInsert(tableProperties); else ProcessTable(table, tableProperties); } } } // ProcessTablePrompt /// <summary> /// Method to insert a basic table /// Will honour the existing table if passed in /// </summary> private void ProcessTable(mshtmlTable table, HtmlTableProperty tableProperties) { try { // obtain a reference to the body node and indicate table present var bodyNode = (mshtmlDomNode)document.body; bool tableCreated = false; // ensure a table node has been defined to work with if (table.IsNull()) { // create the table and indicate it was created table = (mshtmlTable)document.createElement(TABLE_TAG); tableCreated = true; } // define the table border, width, cell padding and spacing table.border = tableProperties.BorderSize; if (tableProperties.TableWidth > 0) table.width = (tableProperties.TableWidthMeasurement == MeasurementOption.Pixel) ? string.Format("{0}", tableProperties.TableWidth) : string.Format("{0}%", tableProperties.TableWidth); else table.width = string.Empty; table.align = tableProperties.TableAlignment != HorizontalAlignOption.Default ? tableProperties.TableAlignment.ToString().ToLower() : string.Empty; table.cellPadding = tableProperties.CellPadding.ToString(CultureInfo.InvariantCulture); table.cellSpacing = tableProperties.CellSpacing.ToString(CultureInfo.InvariantCulture); // define the given table caption and alignment string caption = tableProperties.CaptionText; mshtmlTableCaption tableCaption = table.caption; if (!caption.IsNullOrEmpty()) { // ensure table caption correctly defined if (tableCaption.IsNull()) tableCaption = table.createCaption(); ((mshtmlElement)tableCaption).innerText = caption; if (tableProperties.CaptionAlignment != HorizontalAlignOption.Default) tableCaption.align = tableProperties.CaptionAlignment.ToString().ToLower(); if (tableProperties.CaptionLocation != VerticalAlignOption.Default) tableCaption.vAlign = tableProperties.CaptionLocation.ToString().ToLower(); } else { // if no caption specified remove the existing one if (!tableCaption.IsNull()) { // prior to deleting the caption the contents must be cleared ((mshtmlElement)tableCaption).innerText = null; table.deleteCaption(); } } // determine the number of rows one has to insert int numberRows, numberCols; if (tableCreated) { numberRows = Math.Max((int)tableProperties.TableRows, 1); } else { numberRows = Math.Max((int)tableProperties.TableRows, 1) - table.rows.length; } // layout the table structure in terms of rows and columns table.cols = tableProperties.TableColumns; if (tableCreated) { // this section is an optimization based on creating a new table // the section below works but not as efficiently numberCols = Math.Max((int)tableProperties.TableColumns, 1); // insert the appropriate number of rows mshtmlTableRow tableRow; for (int idxRow = 0; idxRow < numberRows; idxRow ) { tableRow = (mshtmlTableRow)table.insertRow(); // add the new columns to the end of each row for (int idxCol = 0; idxCol < numberCols; idxCol ) { tableRow.insertCell(); } } } else { // if the number of rows is increasing insert the decrepency if (numberRows > 0) { // insert the appropriate number of rows for (int idxRow = 0; idxRow < numberRows; idxRow ) { table.insertRow(); } } else { // remove the extra rows from the table for (int idxRow = numberRows; idxRow < 0; idxRow ) { table.deleteRow(table.rows.length - 1); } } // have the rows constructed // now ensure the columns are correctly defined for each row mshtmlElementCollection rows = table.rows; foreach (mshtmlTableRow tableRow in rows) { numberCols = Math.Max((int)tableProperties.TableColumns, 1) - tableRow.cells.length; if (numberCols > 0) { // add the new column to the end of each row for (int idxCol = 0; idxCol < numberCols; idxCol ) { tableRow.insertCell(); } } else { // reduce the number of cells in the given row // remove the extra rows from the table for (int idxCol = numberCols; idxCol < 0; idxCol ) { tableRow.deleteCell(tableRow.cells.length - 1); } } } } // if the table was created then it requires insertion into the DOM // otherwise property changes are sufficient if (tableCreated) { // table processing all complete so insert into the DOM var tableNode = (mshtmlDomNode)table; var tableElement = (mshtmlElement)table; mshtmlTextRange textRange = GetTextRange(); // final insert dependant on what user has selected if (!textRange.IsNull()) { // text range selected so overwrite with a table try { string selectedText = textRange.text; if (!selectedText.IsNull()) { // place selected text into first cell var tableRow = (mshtmlTableRow)table.rows.item(0, null); ((mshtmlElement)tableRow.cells.item(0, null)).innerText = selectedText; } textRange.pasteHTML(tableElement.outerHTML); } catch (Exception ex) { throw new HtmlEditorException("Invalid Text selection for the Insertion of a Table.", "ProcessTable", ex); } } else { mshtmlControlRange controlRange = GetAllControls(); if (!controlRange.IsNull()) { // overwrite any controls the user has selected try { // clear the selection and insert the table // only valid if multiple selection is enabled for (int idx = 1; idx < controlRange.length; idx ) { controlRange.remove(idx); } controlRange.item(0).outerHTML = tableElement.outerHTML; // this should work with initial count set to zero // controlRange.add((mshtmlControlElement)table); } catch (Exception ex) { throw new HtmlEditorException("Cannot Delete all previously Controls selected.", "ProcessTable", ex); } } else { // insert the table at the end of the HTML bodyNode.appendChild(tableNode); } } } else { // table has been correctly defined as being the first selected item // need to remove other selected items mshtmlControlRange controlRange = GetAllControls(); if (!controlRange.IsNull()) { // clear the controls selected other than than the first table // only valid if multiple selection is enabled for (int idx = 1; idx < controlRange.length; idx ) { controlRange.remove(idx); } } } } catch (Exception ex) { // throw an exception indicating table structure change error throw new HtmlEditorException("Unable to modify Html Table properties.", "ProcessTable", ex); } } //ProcessTable /// <summary> /// Method to determine if the current selection is a table /// If found will return the table element /// </summary> private void GetTableElement(out mshtmlTable table, out mshtmlTableRow row) { row = null; mshtmlTextRange range = GetTextRange(); try { // first see if the table element is selected table = GetFirstControl() as mshtmlTable; // if table not selected then parse up the selection tree if (table.IsNull() && !range.IsNull()) { var element = range.parentElement(); // parse up the tree until the table element is found while (!element.IsNull() && table.IsNull()) { element = element.parentElement; // extract the Table properties var htmlTable = element as mshtmlTable; if (!htmlTable.IsNull()) { table = htmlTable; } // extract the Row properties var htmlTableRow = element as mshtmlTableRow; if (!htmlTableRow.IsNull()) { row = htmlTableRow; } } } } catch (Exception) { // have unknown error so set return to null table = null; row = null; } } //GetTableElement /// <summary> /// Method to return the currently selected Html Table Element /// </summary> private mshtmlTable GetTableElement() { // define the table and row elements and obtain there values mshtmlTable table; mshtmlTableRow row; GetTableElement(out table, out row); // return the defined table element return table; } /// <summary> /// Given an Html Table Element determines the table properties /// Returns the properties as an HtmlTableProperty class /// </summary> private HtmlTableProperty GetTableProperties(mshtmlTable table) { // define a set of base table properties var tableProperties = new HtmlTableProperty(true); // if user has selected a table extract those properties if (!table.IsNull()) { try { // have a table so extract the properties mshtmlTableCaption caption = table.caption; // if have a caption persist the values if (!caption.IsNull()) { tableProperties.CaptionText = ((mshtmlElement)table.caption).innerText; if (!caption.align.IsNull()) tableProperties.CaptionAlignment = (HorizontalAlignOption)typeof(HorizontalAlignOption).TryParseEnum(caption.align, HorizontalAlignOption.Default); if (!caption.vAlign.IsNull()) tableProperties.CaptionLocation = (VerticalAlignOption)typeof(VerticalAlignOption).TryParseEnum(caption.vAlign, VerticalAlignOption.Default); } // look at the table properties if (!GeneralUtil.IsNull(table.border)) tableProperties.BorderSize =GeneralUtil.TryParseByte(table.border.ToString(),tableProperties.BorderSize); if (!table.align.IsNull()) tableProperties.TableAlignment = (HorizontalAlignOption)typeof(HorizontalAlignOption).TryParseEnum(table.align, HorizontalAlignOption.Default); // define the table rows and columns int rows = Math.Min(table.rows.length, Byte.MaxValue); int cols = Math.Min(table.cols, Byte.MaxValue); if (cols == 0 && rows > 0) { // cols value not set to get the maxiumn number of cells in the rows foreach (mshtmlTableRow tableRow in table.rows) { cols = Math.Max(cols, tableRow.cells.length); } } tableProperties.TableRows = (byte)Math.Min(rows, byte.MaxValue); tableProperties.TableColumns = (byte)Math.Min(cols, byte.MaxValue); // define the remaining table properties if (!GeneralUtil.IsNull(table.cellPadding)) tableProperties.CellPadding = GeneralUtil.TryParseByte(table.cellPadding.ToString(),tableProperties.CellPadding); if (!GeneralUtil.IsNull(table.cellSpacing)) tableProperties.CellSpacing = GeneralUtil.TryParseByte(table.cellSpacing.ToString(),tableProperties.CellSpacing); if (!GeneralUtil.IsNull(table.width)) { string tableWidth = table.width.ToString(); if (tableWidth.TrimEnd(null).EndsWith("%")) { tableProperties.TableWidth = tableWidth.Remove(tableWidth.LastIndexOf("%", StringComparison.Ordinal), 1).TryParseUshort(tableProperties.TableWidth); tableProperties.TableWidthMeasurement = MeasurementOption.Percent; } else { tableProperties.TableWidth = tableWidth.TryParseUshort(tableProperties.TableWidth); tableProperties.TableWidthMeasurement = MeasurementOption.Pixel; } } else { tableProperties.TableWidth = 0; tableProperties.TableWidthMeasurement = MeasurementOption.Pixel; } } catch (Exception ex) { // throw an exception indicating table structure change be determined throw new HtmlEditorException("Unable to determine Html Table properties.", "GetTableProperties", ex); } } // return the table properties return tableProperties; } //GetTableProperties /// <summary> /// Method to return a table defintion based on the user selection /// If table selected (or insertion point within table) returns these values /// </summary> public void GetTableDefinition(out HtmlTableProperty table, out bool tableFound) { // see if a table selected or insertion point inside a table mshtmlTable htmlTable = GetTableElement(); // process according to table being defined if (htmlTable.IsNull()) { table = new HtmlTableProperty(true); tableFound = false; } else { table = GetTableProperties(htmlTable); tableFound = true; } } //GetTableDefinition /// <summary> /// Method to determine if the insertion point or selection is a table /// </summary> private bool IsParentTable() { // see if a table selected or insertion point inside a table mshtmlTable htmlTable = GetTableElement(); // process according to table being defined if (htmlTable.IsNull()) { return false; } return true; } //IsParentTable /// <summary> /// Method to insert a horizontal line in the body /// If have a control range rather than text range one could overwrite the controls with the line /// </summary> public void InsertLine() { mshtmlTextRange range = GetTextRange(); if (range != null) { ExecuteCommandRange(range, HTML_COMMAND_INSERT_HORIZONTAL_RULE, null); } else { throw new HtmlEditorException("Invalid Selection for Line insertion.", "InsertLine"); } } //InsertLine /// <summary> /// Method to Tab the current line to the left /// </summary> public void Outdent() { ExecuteCommandRange(HTML_COMMAND_OUTDENT, null); } //Outdent /// <summary> /// Method to Tab the current line to the right /// </summary> public void Indent() { ExecuteCommandRange(HTML_COMMAND_INDENT, null); } //Indent /// <summary> /// Method to insert an unordered list /// </summary> public void InsertUnorderedList() { ExecuteCommandRange(HTML_COMMAND_INSERT_UNORDERED_LIST, null); FormatSelectionChange(); } //InsertUnorderedList /// <summary> /// Method to insert an ordered list /// </summary> public void InsertOrderedList() { ExecuteCommandRange(HTML_COMMAND_INSERT_ORDERED_LIST, null); FormatSelectionChange(); } //InsertOrderedList /// <summary> /// Method using the document to toggle the selection with a Superscript tag /// </summary> public void Superscript() { ExecuteCommandRange(HTML_COMMAND_SUPERSCRIPT, null); FormatSelectionChange(); } //Superscript /// <summary> /// Method using the document to toggle the selection with a Subscript tag /// </summary> public void Subscript() { ExecuteCommandRange(HTML_COMMAND_SUBSCRIPT, null); FormatSelectionChange(); } //Subscript /// <summary> /// Method to select the entire document contents /// </summary> public void SelectAll() { ExecuteCommandDocument(HTML_COMMAND_SELECT_ALL); } //SelectAll #endregion #endregion private void tsbNew_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbOpen_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbSave_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbPreview_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbShowHTML_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbCopy_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbCut_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbPaste_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbDelete_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbFind_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } /// <summary> /// Method to ensure dialog resembles the user form characteristics /// </summary> private void DefineDialogProperties(Form dialog) { // set ambient control properties if (!ParentForm.IsNull()) { dialog.Font = ParentForm.Font; dialog.ForeColor = ParentForm.ForeColor; dialog.BackColor = ParentForm.BackColor; dialog.Cursor = ParentForm.Cursor; dialog.RightToLeft = ParentForm.RightToLeft; } // define location and control style as system dialog.StartPosition = FormStartPosition.CenterParent; } //DefineDialogProperties /// <summary> /// Method to determine if the tag name is of the correct type /// A string comparision is made whilst ignoring case /// </summary> private bool IsStringEqual(string tagText, string tagType) { return (String.Compare(tagText, tagType, StringComparison.OrdinalIgnoreCase) == 0); } //IsStringEqual private void tsbRemoveFormat_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbJustifyCenter_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbJustifyLeft_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbJustifyRight_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbUnderline_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbItalic_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbBold_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbStrikeThrough_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbCreateLink_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbUnlink_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbInsertImage_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbInsertHorizontalRule_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbOutdent_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbIndent_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbInsertUnorderedList_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbInsertOrderedList_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbAbout_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbJustifyFull_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsmiInsertTable_Click(object sender, EventArgs e) { var menuItem = (ToolStripMenuItem)sender; var command = (string)menuItem.Tag; ProcessCommand(command); } private void tsbWordCount_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbSuperscript_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbSubscript_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbPrint_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbDate_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbTime_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbSpellCheck_Click(object sender, EventArgs e) { Debug.Assert(wb.Document != null, "wb.Document != null"); Debug.Assert(wb.Document.Body != null, "wb.Document.Body != null"); spellCheck.Text = wb.Document.Body.InnerHtml; spellCheck.SpellCheck(); } private void tsbAutoLayout_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbUndo_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbRedo_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } private void tsbClearWord_Click(object sender, EventArgs e) { var button = (ToolStripButton)sender; var command = (string)button.Tag; ProcessCommand(command); } /// <summary> /// Method to perform the process of showing the context menus /// </summary> private void DocumentContextMenu(object sender, HtmlElementEventArgs e) { // if in readonly mode display the standard context menu // otherwise display the editing context menu if (!_readOnly) { // should disable inappropriate commands tsmiTable.Visible = IsParentTable(); // display the text processing context menu cmsHtml.Show(wb, e.MousePosition); // cancel the standard menu and event bubbling e.BubbleEvent = false; e.ReturnValue = false; } } //DocumentContextMenu /// <summary> /// Method to perform the process of selection change /// </summary> private void DocumentSelectionChange(object sender, EventArgs e) { // if not in readonly mode process the selection change if (!_readOnly) { FormatSelectionChange(); } } //DocumentSelectionChange /// <summary> /// Ensures the toolbar is correctly displaying state /// </summary> private void FormatSelectionChange() { // don't process until bowser is create. if (wb.IsHandleCreated == false) return; SetupKeyListener(); tsbBold.Checked = IsBold(); tsbItalic.Checked = IsItalic(); tsbUnderline.Checked = IsUnderline(); tsbStrikeThrough.Checked = IsStrikeThrough(); tsbInsertOrderedList.Checked = IsOrderedList(); tsbInsertUnorderedList.Checked = IsUnorderedList(); tsbJustifyLeft.Checked = IsJustifyLeft(); tsbJustifyCenter.Checked = IsJustifyCenter(); tsbJustifyRight.Checked = IsJustifyRight(); tsbJustifyFull.Checked = IsJustifyFull(); tsbSubscript.Checked = IsSubscript(); tsbSuperscript.Checked = IsSuperscript(); tsbUndo.Enabled = IsUndo(); tsbRedo.Enabled = IsRedo(); tsbUnlink.Enabled = IsUnlink(); UpdateFontComboBox(); UpdateFontSizeComboBox(); } /// <summary> /// Method to perform the process of key being pressed /// </summary> private void DocumentKeyPress(object sender, EventArgs e) { // define the event object being processes and review the key being pressed mshtmlEventObject eventObject = document.parentWindow.@event; if (eventObject.ctrlKey) { switch (eventObject.keyCode) { case 65: SelectAll(); eventObject.returnValue = true; break; case 72: FindReplacePrompt(false); eventObject.returnValue = false; break; } } if ((eventObject.keyCode != 13)) return; if (EnterToBR) { var range = GetTextRange(); Debug.Assert(range != null, "range != null"); range.pasteHTML(!eventObject.shiftKey ? "<br>" : "<P> </P>"); range.collapse(); range.@select(); } if (!eventObject.shiftKey) { eventObject.returnValue = SetupKeyListener(); } eventObject.returnValue = true; } //DocumentKeyPress private void Selector_TableSizeSelected(object sender, TableSizeEventArgs e) { // if user has selected a table create a reference var table = GetFirstControl() as mshtmlTable; // define the base set of table properties HtmlTableProperty tableProperties = GetTableProperties(table); tableProperties.TableRows =(byte)e.SelectedSize.Height; tableProperties.TableColumns = (byte)e.SelectedSize.Width; if (table.IsNull()) TableInsert(tableProperties); else ProcessTable(table, tableProperties); } private void DropDown_Opening(object sender, CancelEventArgs e) { var c = tsddbInsertTable.DropDown as ToolStripTableSizeSelector; if (c != null) { c.Selector.SelectedSize = new Size(0, 0); c.Selector.VisibleRange = new Size(10, 10); } } /// <summary> /// 初始化工具栏和邮件菜单 /// </summary> private void InitUi() { //初始化插入表格部分 var dropDown = new ToolStripTableSizeSelector(); dropDown.Opening = DropDown_Opening; dropDown.Selector.TableSizeSelected = Selector_TableSizeSelected; tsddbInsertTable.DropDown = dropDown; var tsmiInsertTable = new ToolStripMenuItem { Image = Resources.InsertTable, Name = "tsmiInsertTable", Size = new Size(152, 22), Text = Resources.strInsertTable, Tag = "InsertTable" }; tsmiInsertTable.Click = tsmiInsertTable_Click; tsddbInsertTable.DropDownItems.Add(tsmiInsertTable); string removeButton = ConfigurationManager.AppSettings["removeButtons"]; if (!removeButton.IsNullOrEmpty()) { var removeButtons = removeButton.Split(','); foreach (var button in removeButtons) { foreach (var item in tsTopToolBar.Items) { if (item is ToolStripButton) { var tsb = item as ToolStripButton; if (String.CompareOrdinal(tsb.Tag.ToString(), button) == 0) { tsb.Visible = false; break; } } else if (item is ToolStripDropDownButton) { var tsddb = item as ToolStripDropDownButton; if (String.CompareOrdinal(tsddb.Tag.ToString(), button) == 0) { tsddb.Visible = false; break; } } else if (item is ToolStripFontComboBox) { var tsfcb = item as ToolStripFontComboBox; if (String.CompareOrdinal(tsfcb.Tag.ToString(), button) == 0) { tsfcb.Visible = false; break; } } else if (item is ToolStripComboBox) { var tscb = item as ToolStripComboBox; if (String.CompareOrdinal(tscb.Tag.ToString(), button) == 0) { tscb.Visible = false; break; } } } } } string removeMenu = ConfigurationManager.AppSettings["removeMenus"]; if (!string.IsNullOrEmpty(removeMenu)) { var removeMenus = removeMenu.Split(','); foreach (var menu in removeMenus) { foreach (var item in cmsHtml.Items) { if (item is ToolStripMenuItem) { var tsmi = item as ToolStripMenuItem; if (String.CompareOrdinal(tsmi.Tag.ToString(), menu) == 0) { tsmi.Visible = false; break; } } } } } } private void HtmlEditor_Load(object sender, EventArgs e) { tsTopToolBar.Dock = DockStyle.Top; InitUi(); HTMLEditHelper.DOMDocument = _doc; Focus(); } #if VS2010 public static string ClearWord(string sourceText, bool bIgnoreFont = true, bool bRemoveStyles = true, bool cleanWordKeepsStructure = true) { return ClearWordNoDefult(sourceText, bIgnoreFont, bRemoveStyles, cleanWordKeepsStructure); } #endif private static String DeCompressWMZOREMZFile(String wmzoremzFile) { MemoryStream decompressStream = new MemoryStream(File.ReadAllBytes(wmzoremzFile)); GZipStream gzipStream = new GZipStream(decompressStream, CompressionMode.Decompress); MemoryStream outStream = new MemoryStream(); int readCount; byte[] data = new byte[2048]; do { readCount = gzipStream.Read(data, 0, data.Length); outStream.Write(data, 0, readCount); } while (readCount == 2048); String imgFile = Path.GetDirectoryName(wmzoremzFile) "\\" Path.GetFileNameWithoutExtension(wmzoremzFile) (Path.GetExtension(wmzoremzFile) == ".wmz" ? ".wmf" : ".emf"); File.WriteAllBytes(imgFile, outStream.GetBuffer()); return imgFile; } public static string ReplaceWordImageFile(string sourceText) { var reg = new Regex(@"(?is)<v:imagedata[^>]*?src=(['""\s]?)((?:(?!topics)[^'""\s])*)\1[^>]*?>", RegexOptions.IgnoreCase); foreach (Match m in reg.Matches(sourceText)) { switch (Path.GetExtension(m.Groups[2].Value)) { case ".wmz": case ".emz": { string temp = m.Groups[0].Value.Replace(m.Groups[2].Value, DeCompressWMZOREMZFile(m.Groups[2].Value.StartsWith("file:///") ? m.Groups[2].Value.Substring(8) : m.Groups[2].Value)); sourceText = sourceText.Replace(m.Groups[0].Value, temp); } break; } } sourceText = Regex.Replace(sourceText, @"v:imagedata", "img"); return sourceText; } public static string ClearWordNoDefult(string sourceText, bool bIgnoreFont, bool bRemoveStyles, bool cleanWordKeepsStructure) { sourceText = ReplaceWordImageFile(sourceText); sourceText = Regex.Replace(sourceText, @"<o:p>\s*<\/o:p>", ""); sourceText = Regex.Replace(sourceText, @"<o:p>.*?<\/o:p>", " "); // Remove mso-xxx styles. sourceText = Regex.Replace(sourceText, @"\s*mso-[^:] :[^;""'>] ;?", "", RegexOptions.IgnoreCase); // Remove margin styles. sourceText = Regex.Replace(sourceText, @"\s*MARGIN: 0cm 0cm 0pt\s*;", "", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*MARGIN: 0cm 0cm 0pt\s*""", "\"", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*TEXT-INDENT: 0cm\s*;", "", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*TEXT-INDENT: 0cm\s*""", "\"", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*TEXT-ALIGN: [^\s;] ;?""", "\"", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*PAGE-BREAK-BEFORE: [^\s;] ;?""", "\"", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*FONT-VARIANT: [^\s;] ;?""", "\"", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*tab-stops:[^;""]*;?", "", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*tab-stops:[^""]*", "", RegexOptions.IgnoreCase); // Remove FONT face attributes. if (bIgnoreFont) { sourceText = Regex.Replace(sourceText, @"\s*face=""[^""]*""", "", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*face=[^ >]*", "", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"\s*FONT-FAMILY:[^;""]*;?", "", RegexOptions.IgnoreCase); } // Remove Class attributes sourceText = Regex.Replace(sourceText, @"<(\w[^>]*) class=([^ |>]*)([^>]*)", "<$1$3", RegexOptions.IgnoreCase); // Remove styles. if (bRemoveStyles) sourceText = Regex.Replace(sourceText, @"<(\w[^>]*) style=""([^\""]*)""([^>]*)", "<$1$3", RegexOptions.IgnoreCase); // Remove empty styles. sourceText = Regex.Replace(sourceText, @"\s*style=""\s*""", "", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<SPAN\s*[^>]*>\s* \s*<\/SPAN>", " ", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<SPAN\s*[^>]*><\/SPAN>", "", RegexOptions.IgnoreCase); // Remove Lang attributes sourceText = Regex.Replace(sourceText, @"<(\w[^>]*) lang=([^ |>]*)([^>]*)", "<$1$3", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<SPAN\s*>(.*?)<\/SPAN>", "$1", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<FONT\s*>(.*?)<\/FONT>", "$1", RegexOptions.IgnoreCase); // Remove XML elements and declarations sourceText = Regex.Replace(sourceText, @"<\\?\?xml[^>]*>", "", RegexOptions.IgnoreCase); // Remove Tags with XML namespace declarations: <o:p><\/o:p> sourceText = Regex.Replace(sourceText, @"<\/?\w :[^>]*>", "", RegexOptions.IgnoreCase); // Remove comments [SF BUG-1481861]. sourceText = Regex.Replace(sourceText, @"<\!--.*?-->/", ""); sourceText = Regex.Replace(sourceText, @"<(U|I|STRIKE)> <\/\1>", " "); sourceText = Regex.Replace(sourceText, @"<H\d>\s*<\/H\d>", "", RegexOptions.IgnoreCase); // Remove "display:none" tags. sourceText = Regex.Replace(sourceText, @"<(\w )[^>]*\sstyle=""[^""]*DISPLAY\s?:\s?none(.*?)<\/\1>", "", RegexOptions.IgnoreCase); // Remove language tags sourceText = Regex.Replace(sourceText, @"<(\w[^>]*) language=([^ |>]*)([^>]*)", "<$1$3", RegexOptions.IgnoreCase); // Remove onmouseover and onmouseout events (from MS Word comments effect) sourceText = Regex.Replace(sourceText, @"<(\w[^>]*) onmouseover=""([^\""]*)""([^>]*)", "<$1$3", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<(\w[^>]*) onmouseout=""([^\""]*)""([^>]*)", "<$1$3", RegexOptions.IgnoreCase); if (cleanWordKeepsStructure) { // The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px"> sourceText = Regex.Replace(sourceText, @"<H(\d)([^>]*)>", "<h$1>", RegexOptions.IgnoreCase); // Word likes to insert extra <font> tags, when using MSIE. (Wierd). sourceText = Regex.Replace(sourceText, @"<(H\d)><FONT[^>]*>(.*?)<\/FONT><\/\1>", @"<$1>$2<\/$1>", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<(H\d)><EM>(.*?)<\/EM><\/\1>", @"<$1>$2<\/$1>", RegexOptions.IgnoreCase); } else { sourceText = Regex.Replace(sourceText, @"<H1([^>]*)>", @"<div$1><b><font size=""6"">", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<H2([^>]*)>", @"<div$1><b><font size=""5"">", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<H3([^>]*)>", @"<div$1><b><font size=""4"">", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<H4([^>]*)>", @"<div$1><b><font size=""3"">", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<H5([^>]*)>", @"<div$1><b><font size=""2"">", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<H6([^>]*)>", @"<div$1><b><font size=""1"">", RegexOptions.IgnoreCase); sourceText = Regex.Replace(sourceText, @"<\/H\d>", @"<\/font><\/b><\/div>", RegexOptions.IgnoreCase); // Transform <P> to <DIV> //var re = new Regex(@"(<P)([^>]*>.*?)(<\/P>)", RegexOptions.IgnoreCase); // Different because of a IE 5.0 error sourceText = Regex.Replace(sourceText, @"(<P)([^>]*>.*?)(<\/P>)", @"<div$2<\/div>", RegexOptions.IgnoreCase); // Remove empty tags (three times, just to be sure). // This also removes any empty anchor sourceText = Regex.Replace(sourceText, @"<([^\s>] )(\s[^>]*)?>\s*<\/\1>", ""); sourceText = Regex.Replace(sourceText, @"<([^\s>] )(\s[^>]*)?>\s*<\/\1>", ""); sourceText = Regex.Replace(sourceText, @"<([^\s>] )(\s[^>]*)?>\s*<\/\1>", ""); } return sourceText; } private void spellCheck_DeletedWord(object sender, NetSpell.SpellChecker.SpellingEventArgs e) { var htmlDocument = wb.Document; if (htmlDocument != null) if (htmlDocument.Body != null) htmlDocument.Body.InnerHtml = e.Text; } private void spellCheck_ReplacedWord(object sender, NetSpell.SpellChecker.ReplaceWordEventArgs e) { Debug.Assert(wb.Document != null, "wb.Document != null"); Debug.Assert(wb.Document.Body != null, "wb.Document.Body != null"); wb.Document.Body.InnerHtml = e.Text; } #region Fonts and Color Handling //To handle the fact that setting SelectedIndex property calls SelectedIndexChanged event //We set this value to true whenever SelectedIndex is set. private bool _internalCall; private void SetupComboFontSize() { tscbFontSize.Items.Add("1 (8 pt)"); tscbFontSize.Items.Add("2 (10 pt)"); tscbFontSize.Items.Add("3 (12 pt)"); tscbFontSize.Items.Add("4 (14 pt)"); tscbFontSize.Items.Add("5 (18 pt)"); tscbFontSize.Items.Add("6 (24 pt)"); tscbFontSize.Items.Add("7 (36 pt)"); tscbFontSize.Click = tscbFontSize_Click; tscbFontSize.SelectedIndexChanged = tscbFontSize_SelectedIndexChanged; } private void tscbFontSize_Click(object sender, EventArgs e) { _internalCall = false; } /// <summary> /// Set editor's current selection to the value of the font size combo box. /// Ignore if the timer is currently updating the font size to synchronize /// the font size combo box with the editor's current selection. /// </summary> /// <param name="sender">the sender</param> /// <param name="e">EventArgs</param> private void tscbFontSize_SelectedIndexChanged(object sender, EventArgs e) { try { //Fontsize changed 1 to 7 if ((tscbFontSize.SelectedIndex > -1) && (!_internalCall)) { if (_updatingFontSize) return; int obj = tscbFontSize.SelectedIndex 1; switch (obj) { 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; } Focus(); } _internalCall = false; } catch { } } /// <summary> /// Called when the font combo box has changed. /// Ignores the event when the timer is updating the font combo Box /// to synchronize the editor selection with the font combo box. /// </summary> /// <param name="sender">the sender</param> /// <param name="e">EventArgs</param> private void tsfcbFontName_SelectedIndexChanged(object sender, EventArgs e) { if (_updatingFontName) return; FontFamily ff; try { ff = new FontFamily(tsfcbFontName.Text); } catch (Exception) { _updatingFontName = true; tsfcbFontName.Text = FontName.GetName(0); _updatingFontName = false; return; } FontName = ff; Focus(); } #endregion #region Private variables and methods private void SynchFont(string sTagName) { //Times Roman New object obj = QueryCommandRange(HTML_COMMAND_FONTNAME); if (obj.IsNull()) return; string fontname = obj.ToString(); obj = QueryCommandRange(HTML_COMMAND_FONTSIZE); if (obj.IsNull()) return; //Could indicate a headingxxx, P, or BODY _internalCall = true; if (obj.ToString().Length > 0) tscbFontSize.SelectedIndex = Convert.ToInt32(obj) - 1; //x (x - 1) else AdjustForHeading(sTagName); tsfcbFontName.Text = fontname; } private void AdjustForHeading(string sTag) { if (sTag.IsNullOrEmpty()) return; int index; if (sTag == "H1") index = 5; //24pt else if (sTag == "H2") index = 4; //18pt else if (sTag == "H3") index = 3; //14pt else if (sTag == "H4") index = 2; //12pt else if (sTag == "H5") index = 1; //10pt else if (sTag == "H6") index = 0; //8pt else return; //do nothing _internalCall = true; tscbFontSize.SelectedIndex = index; } /// <summary> /// Set up a key listener on the body once. /// The key listener checks for specific key strokes and takes /// special action in certain cases. /// </summary> /// <returns></returns> private bool SetupKeyListener() { // handle enter code cancellation bool cancel = false; if (!EnterKeyEvent.IsNull()) { var args = new EnterKeyEventArgs(); EnterKeyEvent(this, args); cancel = args.Cancel; } return cancel; } /// <summary> /// Determine whether the current block is left justified. /// </summary> /// <returns>true if left justified, otherwise false</returns> public bool IsJustifyLeft() { return ExecuteCommandQuery(HTML_COMMAND_JUSTIFY_LEFT); } /// <summary> /// Determine whether the current block is right justified. /// </summary> /// <returns>true if right justified, otherwise false</returns> public bool IsJustifyRight() { return ExecuteCommandQuery(HTML_COMMAND_JUSTIFY_RIGHT); } /// <summary> /// Determine whether the current block is center justified. /// </summary> /// <returns>true if center justified, false otherwise</returns> public bool IsJustifyCenter() { return ExecuteCommandQuery(HTML_COMMAND_JUSTIFY_CENTER); } /// <summary> /// Determine whether the current block is full justified. /// </summary> /// <returns>true if full justified, false otherwise</returns> public bool IsJustifyFull() { return ExecuteCommandQuery(HTML_COMMAND_JUSTIFY_FULL); } /// <summary> /// Determine whether the current selection is in Bold mode. /// </summary> /// <returns>whether or not the current selection is Bold</returns> public bool IsBold() { return ExecuteCommandQuery(HTML_COMMAND_BOLD); } /// <summary> /// Determine whether the current selection is in Italic mode. /// </summary> /// <returns>whether or not the current selection is Italicized</returns> public bool IsItalic() { return ExecuteCommandQuery(HTML_COMMAND_ITALIC); } /// <summary> /// Determine whether the current selection is in Underline mode. /// </summary> /// <returns>whether or not the current selection is Underlined</returns> public bool IsUnderline() { return ExecuteCommandQuery(HTML_COMMAND_UNDERLINE); } /// <summary> /// Determine whether the current selection is in StrikeThrough mode. /// </summary> /// <returns>whether or not the current selection is StrikeThrough</returns> public bool IsStrikeThrough() { return ExecuteCommandQuery(HTML_COMMAND_STRIKE_THROUGH); } /// <summary> /// Determine whether the current selection is in Subscript mode. /// </summary> /// <returns>whether or not the current selection is Subscript</returns> public bool IsSubscript() { return ExecuteCommandQuery(HTML_COMMAND_SUBSCRIPT); } /// <summary> /// Determine whether the current selection is in Superscript mode. /// </summary> /// <returns>whether or not the current selection is Superscript</returns> public bool IsSuperscript() { return ExecuteCommandQuery(HTML_COMMAND_SUPERSCRIPT); } /// <summary> /// Determine whether the current paragraph is an ordered list. /// </summary> /// <returns>true if current paragraph is ordered, false otherwise</returns> public bool IsOrderedList() { return ExecuteCommandQuery(HTML_COMMAND_INSERT_ORDERED_LIST); } /// <summary> /// Determine whether the current paragraph is an unordered list. /// </summary> /// <returns>true if current paragraph is ordered, false otherwise</returns> public bool IsUnorderedList() { return ExecuteCommandQuery(HTML_COMMAND_INSERT_UNORDERED_LIST); } /// <summary> /// Determine whether the current block can undo. /// </summary> /// <returns>true if current block can undo, false otherwise</returns> public bool IsUndo() { return _doc.queryCommandEnabled(HTML_COMMAND_UNDO); } /// <summary> /// Determine whether the current block can redo. /// </summary> /// <returns>true if current block can redo, false otherwise</returns> public bool IsRedo() { return _doc.queryCommandEnabled(HTML_COMMAND_REDO); } /// <summary> /// Determine whether the current block can unlink. /// </summary> /// <returns>true if current block can unlink, false otherwise</returns> public bool IsUnlink() { return ExecuteCommandQuery(HTML_COMMAND_UNLINK, true); } /// <summary> /// Update the font size combo box. /// Sets a flag to indicate that the combo box is updating, and should /// not update the editor's selection. /// </summary> private void UpdateFontSizeComboBox() { if (!tscbFontSize.Focused) { int foo; switch (FontSize) { case FontSize.One: foo = 0; break; case FontSize.Two: foo = 1; break; case FontSize.Three: foo = 2; break; case FontSize.Four: foo = 3; break; case FontSize.Five: foo = 4; break; case FontSize.Six: foo = 5; break; case FontSize.Seven: foo = 6; break; case FontSize.NA: foo = -1; break; default: foo = 2; break; } //string fontsize = Convert.ToString(foo); if (foo != tscbFontSize.SelectedIndex) { _updatingFontSize = true; tscbFontSize.SelectedIndex = foo; _updatingFontSize = false; } } } /// <summary> /// Update the font combo box. /// Sets a flag to indicate that the combo box is updating, and should /// not update the editor's selection. /// </summary> private void UpdateFontComboBox() { if (!tsfcbFontName.Focused) { FontFamily fam = FontName; if (!fam.IsNull()) { string fontname = fam.Name; if (fontname != tsfcbFontName.Text) { _updatingFontName = true; tsfcbFontName.Text = fontname; _updatingFontName = false; } } } } /// <summary> /// Get/Set the current font size. /// </summary> [Browsable(false)] public FontSize FontSize { get { if (QueryCommandRange(HTML_COMMAND_FONTSIZE).IsNull()) return FontSize.NA; switch (QueryCommandRange(HTML_COMMAND_FONTSIZE).ToString()) { 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; } if (!wb.Document.IsNull()) wb.Document.ExecCommand(HTML_COMMAND_FONTSIZE, false, sz.ToString(CultureInfo.InvariantCulture)); } } /// <summary> /// Get/Set the current font name. /// </summary> [Browsable(false)] public FontFamily FontName { get { var name = QueryCommandRange(HTML_COMMAND_FONTNAME) as string; if (name.IsNull()) return null; return new FontFamily(name); } set { if (!value.IsNull() && !wb.Document.IsNull()) { wb.Document.ExecCommand(HTML_COMMAND_FONTNAME, false, value.Name); } } } #endregion private void wb_Navigating(object sender, WebBrowserNavigatingEventArgs e) { string url = e.Url.ToString(); if (!codeNavigate) { // call the appropriate event processing var navigateArgs = new HtmlNavigationEventArgs(url); OnHtmlNavigation(navigateArgs); // process the event based on the navigation option if (navigateArgs.Cancel) { // cancel the navigation e.Cancel = true; } else if (_navigateWindow == NavigateActionOption.NewWindow) { // cancel the current navigation and load url into a new window e.Cancel = true; NavigateToUrl(url, true); } else { // continue with current navigation e.Cancel = false; } } else { // TODO Should ensure the following are no executed for the editor navigation // Scripts // Java // ActiveX Controls // Behaviors // Dialogs // continue with current navigation e.Cancel = false; } } /// <summary> /// Processing for the HtmlNavigation event /// </summary> private void OnHtmlNavigation(HtmlNavigationEventArgs args) { if (!HtmlNavigation.IsNull()) { HtmlNavigation(this, args); } } //OnHtmlNavigation #region MsHtml Command Processing /// <summary> /// Performs a query of the command state /// </summary> private bool ExecuteCommandQuery(string command, bool isEnabled=false) { // obtain the selected range object and query command mshtmlTextRange range = GetTextRange(); return ExecuteCommandQuery(range, command, isEnabled); } //ExecuteCommandQuery /// <summary> /// Executes the queryCommandState on the selected range (given the range) /// </summary> private bool ExecuteCommandQuery(mshtmlTextRange range, string command, bool isEnabled = false) { // set the initial state as false bool retValue = false; try { if (!range.IsNull()) { // ensure command is a valid command and then enabled for the selection if (range.queryCommandSupported(command)) { if (isEnabled) { retValue = range.queryCommandEnabled(command); } else { if (range.queryCommandEnabled(command)) { // mark the selection with the appropriate tag retValue = range.queryCommandState(command); } } } } } catch (Exception ex) { // Unknown error so inform user throw new HtmlEditorException("Unknown MSHTML Error.", command, ex); } // return the value return retValue; } // ExecuteCommandQuery /// <summary> /// Executes the execCommand on the selected range /// </summary> private void ExecuteCommandRange(string command, object data) { // obtain the selected range object and execute command mshtmlTextRange range = GetTextRange(); ExecuteCommandRange(range, command, data); } // ExecuteCommandRange /// <summary> /// Executes the execCommand on the selected range (given the range) /// </summary> private void ExecuteCommandRange(mshtmlTextRange range, string command, object data) { try { if (!range.IsNull()) { // ensure command is a valid command and then enabled for the selection if (range.queryCommandSupported(command)) { if (range.queryCommandEnabled(command)) { // mark the selection with the appropriate tag range.execCommand(command, false, data); } } } } catch (Exception ex) { // Unknown error so inform user throw new HtmlEditorException("Unknown MSHTML Error.", command, ex); } } // ExecuteCommandRange /// <summary> /// Executes the execCommand on the document with a system prompt /// </summary> private void ExecuteCommandDocumentPrompt(string command) { ExecuteCommandDocument(command, true); } // ExecuteCommandDocumentPrompt /// <summary> /// Executes the execCommand on the document with a system prompt /// </summary> private void ExecuteCommandDocument(string command, bool prompt = false) { try { // ensure command is a valid command and then enabled for the selection if (document.queryCommandSupported(command)) { // if (document.queryCommandEnabled(command)) {} // Test fails with a COM exception if command is Print // execute the given command document.execCommand(command, prompt, null); } } catch (Exception ex) { // Unknown error so inform user throw new HtmlEditorException("Unknown MSHTML Error.", command, ex); } } // ExecuteCommandDocumentPrompt /// <summary> /// Determines the value of the command /// </summary> private object QueryCommandRange(string command) { // obtain the selected range object and execute command mshtmlTextRange range = GetTextRange(); return !range.IsNull()? QueryCommandRange(range, command) : null; } // QueryCommandRange /// <summary> /// Determines the value of the command /// </summary> private object QueryCommandRange(mshtmlTextRange range, string command) { object retValue = null; if (!range.IsNull()) { try { // ensure command is a valid command and then enabled for the selection if (range.queryCommandSupported(command)) { if (range.queryCommandEnabled(command)) { retValue = range.queryCommandValue(command); } } } catch (Exception) { // have unknown error so set return to null retValue = null; } } // return the obtained value return retValue; } //QueryCommandRange /// <summary> /// Gets the selected Html Range Element /// </summary> private mshtmlTextRange GetTextRange() { // define the selected range object mshtmlTextRange range = null; try { // calculate the text range based on user selection mshtmlSelection selection = document.selection; if (IsStringEqual(selection.type, SELECT_TYPE_TEXT) || IsStringEqual(selection.type, SELECT_TYPE_NONE)) { range = (mshtmlTextRange)selection.createRange(); } } catch (Exception) { // have unknown error so set return to null range = null; } return range; } // GetTextRange /// <summary> /// Determines the color of the selected text range /// Returns default value if not text selected /// </summary> private Color GetFontColor() { object fontColor = QueryCommandRange(HTML_COMMAND_FORE_COLOR); return (fontColor is Int32) ? ColorTranslator.FromWin32((int)fontColor) : _bodyForeColor; } //GetFontColor /// <summary> /// Determines the color of the selected text range /// Returns default value if not text selected /// </summary> private Color GetBackColor() { object fontColor = QueryCommandRange(HTML_COMMAND_BACK_COLOR); return (fontColor is Int32) ? ColorTranslator.FromWin32((int)fontColor) : _bodyBackColor; } //GetFontColor /// <summary> /// Gets the first selected Html Control as an Element /// </summary> private mshtmlElement GetFirstControl() { // define the selected range object mshtmlElement control = null; try { // calculate the first control based on the user selection mshtmlSelection selection = document.selection; if (IsStringEqual(selection.type, SELECT_TYPE_CONTROL)) { var range = (mshtmlControlRange)selection.createRange(); if (range.length > 0) control = range.item(0); } } catch (Exception) { // have unknown error so set return to null control = null; } return control; } // GetFirstControl /// <summary> /// Gets all the selected Html Controls as a Control Range /// </summary> /// <returns></returns> private mshtmlControlRange GetAllControls() { // define the selected range object mshtmlControlRange range = null; try { // calculate the first control based on the user selection mshtmlSelection selection = document.selection; if (IsStringEqual(selection.type, SELECT_TYPE_CONTROL)) { range = (mshtmlControlRange)selection.createRange(); } } catch (Exception) { // have unknow error so set return to null range = null; } return range; } //GetAllControls #endregion /// <summary> /// Method to process the toolbar command and handle error exception /// </summary> private void ProcessCommand(string command) { try { // Evaluate the Button property to determine which button was clicked. switch (command) { case INTERNAL_COMMAND_NEW: // New document New(); break; case INTERNAL_COMMAND_OPEN: // Open a selected file Open(); break; case INTERNAL_COMMAND_PRINT: // Print the current document Print(); break; case INTERNAL_COMMAND_SAVE: // Saves the current document Save(); break; case INTERNAL_COMMAND_PREVIEW: // Preview the html page Preview(); break; case INTERNAL_COMMAND_SHOWHTML: // View the html contents ShowHTML(); break; case INTERNAL_COMMAND_COPY: // Browser COPY command Copy(); break; case INTERNAL_COMMAND_CUT: // Browser CUT command Cut(); break; case INTERNAL_COMMAND_PASTE: // Browser PASTE command Paste(); break; case INTERNAL_COMMAND_DELETE: // Browser DELETE command Delete(); break; case INTERNAL_COMMAND_UNDO: // Undo the previous editing Undo(); break; case INTERNAL_COMMAND_REDO: // Redo the previous undo Redo(); break; case INTERNAL_COMMAND_FIND: //Find the string u input Find(); break; case INTERNAL_COMMAND_REMOVE_FORMAT: // Browser REMOVEFORMAT command RemoveFormat(); break; case INTERNAL_COMMAND_JUSTIFYCENTER: // Justify Center JustifyCenter(); break; case INTERNAL_COMMAND_JUSTIFYFULL: // Justify Full JustifyFull(); break; case INTERNAL_COMMAND_JUSTIFYLEFT: // Justify Left JustifyLeft(); break; case INTERNAL_COMMAND_JUSTIFYRIGHT: // Justify Right JustifyRight(); break; case INTERNAL_COMMAND_UNDERLINE: // Selection UNDERLINE command Underline(); break; case INTERNAL_COMMAND_ITALIC: // Selection ITALIC command Italic(); break; case INTERNAL_COMMAND_BOLD: // Selection BOLD command Bold(); break; case INTERNAL_COMMAND_FORECOLOR: // FORECOLOR style creation FormatFontColor(tscpForeColor.Color); break; case INTERNAL_COMMAND_BACKCOLOR: // BACKCOLOR style creation FormatBackColor(tscpBackColor.Color); break; case INTERNAL_COMMAND_STRIKETHROUGH: // Selection STRIKETHROUGH command StrikeThrough(); break; case INTERNAL_COMMAND_CREATELINK: // Selection CREATELINK command CreateLink(); break; case INTERNAL_COMMAND_UNLINK: // Selection UNLINK command UnLink(); break; case INTERNAL_COMMAND_INSERTTABLE: // Display a dialog to enable the user to insert a table TableInsertPrompt(); break; case INTERNAL_COMMAND_TABLEPROPERTIES: // Display a dialog to enable the user to modify a table TableModifyPrompt(); break; case INTERNAL_COMMAND_TABLEINSERTROW: // Display a dialog to enable the user to modify a table TableInsertRow(); break; case INTERNAL_COMMAND_TABLEDELETEROW: // Display a dialog to enable the user to modify a table TableDeleteRow(); break; case INTERNAL_COMMAND_INSERTIMAGE: // Display a dialog to enable the user to insert a image InsertImage(); break; case INTERNAL_COMMAND_INSERTHORIZONTALRULE: // Horizontal Line InsertLine(); break; case INTERNAL_COMMAND_OUTDENT: // Tab Left Outdent(); break; case INTERNAL_COMMAND_INDENT: // Tab Right Indent(); break; case INTERNAL_COMMAND_INSERTUNORDEREDLIST: // Unordered List InsertUnorderedList(); break; case INTERNAL_COMMAND_INSERTORDEREDLIST: // Ordered List InsertOrderedList(); break; case INTERNAL_COMMAND_SUPERSCRIPT: // Selection SUPERSCRIPT command Superscript(); break; case INTERNAL_COMMAND_SUBSCRIPT: // Selection SUBSCRIPT command Subscript(); break; case INTERNAL_COMMAND_SELECTALL: // Selects all document content SelectAll(); break; case INTERNAL_COMMAND_WORDCOUNT: // Word count int wordCount = WordCount(); tsslWordCount.Text = string.Format("字数:{0}", wordCount); break; case INTERNAL_COMMAND_INSERTDATE: // Insert date HTMLEditHelper.PasteIntoSelection(DateTime.Now.ToLongDateString()); break; case INTERNAL_COMMAND_INSERTTIME: // Insert time HTMLEditHelper.PasteIntoSelection(DateTime.Now.ToLongTimeString()); break; case INTERNAL_COMMAND_CLEARWORD: // Clear word if (BodyInnerHTML != null) { Debug.Assert(wb.Document != null, "wb.Document != null"); Debug.Assert(wb.Document.Body != null, "wb.Document.Body != null"); #if VS2010 wb.Document.Body.InnerHtml = ClearWord(BodyInnerHTML); #else wb.Document.Body.InnerHtml = ClearWordNoDefult(BodyInnerHTML, true, true, true); #endif } break; case INTERNAL_COMMAND_AUTOLAYOUT: // Auto Layout AutoLayout(); break; case INTERNAL_COMMAND_ABOUT: if (MessageBox.Show(Resources.AboutInfo, Resources.AboutText, MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes) { Process.Start("http://tewuapple.github.com/WinHtmlEditor/"); } break; default: throw new HtmlEditorException("Unknown Operation Being Performed.", command); } } catch (HtmlEditorException ex) { // process the html exception OnHtmlException(new HtmlExceptionEventArgs(ex.Operation, ex)); } catch (Exception ex) { // process the exception OnHtmlException(new HtmlExceptionEventArgs(null, ex)); } // ensure web browser has the focus after command execution Focus(); } //ProcessCommand /// <summary> /// Method to raise an event if a delegeate is assigned for handling exceptions /// </summary> private void OnHtmlException(HtmlExceptionEventArgs args) { if (HtmlException.IsNull()) { // obtain the message and operation // concatenate the message with any inner message string operation = args.Operation; Exception ex = args.ExceptionObject; string message = ex.Message; if (!ex.InnerException.IsNull()) { message = string.Format("{0}\n{1}", message, ex.InnerException.Message); } // define the title for the internal message box string title; if (operation.IsNullOrEmpty()) { title = "Unknown Error"; } else { title = operation " Error"; } // display the error message box MessageBox.Show(this, message, title, MessageBoxButtons.OK, MessageBoxIcon.Error); } else { HtmlException(this, args); } } private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { // get access to the HTMLDocument var htmlDocument = wb.Document; if (!htmlDocument.IsNull()) { document = (mshtmlDocument)htmlDocument.DomDocument; _doc = (mshtmlIHTMLDocument2)htmlDocument.DomDocument; // at this point the document and body has been loaded // so define the event handler for the context menu htmlDocument.ContextMenuShowing = DocumentContextMenu; htmlDocument.AttachEventHandler("onselectionchange", DocumentSelectionChange); htmlDocument.AttachEventHandler("onkeydown", DocumentKeyPress); } body = (mshtmlBody)document.body; // COM Interop Start // once browsing has completed there is the need to setup some options // need to ensure URLs are not modified when html is pasted int hResult; // try to obtain the command target for the web browser document try { // cast the document to a command target var target = (IOleCommandTarget)document; // set the appropriate no url fixups on paste hResult = target.Exec(ref CommandGroup.CGID_MSHTML, (int)CommandId.IDM_NOFIXUPURLSONPASTE, (int)CommandOption.OLECMDEXECOPT_DONTPROMPTUSER, ref EMPTY_PARAMETER, ref EMPTY_PARAMETER); } // catch any exception and map back to the HRESULT catch (Exception ex) { hResult = Marshal.GetHRForException(ex); } // test the HRESULT for a valid operation rebaseUrlsNeeded = hResult != HRESULT.S_OK; // COM Interop End // signalled complete codeNavigate = false; loading = false; // after navigation define the document Url string url = e.Url.ToString(); _bodyUrl = IsStringEqual(url, BLANK_HTML_PAGE) ? string.Empty : url; } /// <summary> /// Called when a key is pressed on the font size combo box. /// The font size in the boxy box is set to the key press value. /// </summary> /// <param name="sender">the sender</param> /// <param name="e">KeyPressEventArgs</param> private void tscbFontSize_KeyPress(object sender, KeyPressEventArgs e) { if (Char.IsNumber(e.KeyChar)) { e.Handled = true; if (e.KeyChar <= '7' && e.KeyChar > '0') tscbFontSize.SelectedIndex = GeneralUtil.ParseInt(e.KeyChar) - 1; } else if (!Char.IsControl(e.KeyChar)) { e.Handled = true; } } /// <summary> /// General Context Meun processing method /// Calls the ProcessCommand with the selected command Tag Text /// </summary> private void ContextEditorClick(object sender, EventArgs e) { var menuItem = (ToolStripMenuItem)sender; var command = (string)menuItem.Tag; ProcessCommand(command); } //contextEditorClick private void tscpBackColor_SelectedColorChanged(object sender, EventArgs e) { var tscp = (ToolStripColorPicker)sender; var command = (string)tscp.Tag; ProcessCommand(command); } private void tscpForeColor_SelectedColorChanged(object sender, EventArgs e) { var tscp = (ToolStripColorPicker)sender; var command = (string)tscp.Tag; ProcessCommand(command); } } }
好例子网口号:伸出你的我的手 — 分享!
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)