/// <summary> /// Sends a win32 message to get the scrollbars' position. /// </summary> /// <returns>a POINT structore containing horizontal and vertical scrollbar position.</returns> private unsafe Win32.POINT GetScrollPos() { Win32.POINT res = new Win32.POINT(); IntPtr ptr = new IntPtr(&res); Win32.SendMessage(Handle, Win32.EM_GETSCROLLPOS, 0, ptr); return(res); }
/// <summary> /// The on text changed overrided. Here we parse the text into RTF for the highlighting. /// </summary> /// <param name="e"></param> protected override void OnTextChanged(EventArgs e) { if (mParsing) { return; } mParsing = true; Win32.LockWindowUpdate(Handle); base.OnTextChanged(e); if (!mIsUndo) { mRedoStack.Clear(); mUndoList.Insert(0, mLastInfo); this.LimitUndo(); mLastInfo = new UndoRedoInfo(Text, GetScrollPos(), SelectionStart); } // Save scroll bar an cursor position, changeing the RTF moves the cursor and scrollbars to top positin Win32.POINT scrollPos = GetScrollPos(); int cursorLoc = SelectionStart; // Created with an estimate of how big the stringbuilder has to be... StringBuilder sb = new StringBuilder((int)(Text.Length * 1.5 + 150)); // Adding RTF header sb.Append(@"{\rtf1\fbidis\ansi\ansicpg1255\deff0\deflang1037{\fonttbl{"); //Font table creation int fontCounter = 0; Hashtable fonts = new Hashtable(); AddFontToTable(sb, Font, ref fontCounter, fonts); foreach (HighlightDescriptor hd in mHighlightDescriptors) { if ((hd.Font != null) && !fonts.ContainsKey(hd.Font.Name)) { AddFontToTable(sb, hd.Font, ref fontCounter, fonts); } } sb.Append("}\n"); // ColorTable sb.Append(@"{\colortbl ;"); Hashtable colors = new Hashtable(); int colorCounter = 1; AddColorToTable(sb, ForeColor, ref colorCounter, colors); AddColorToTable(sb, BackColor, ref colorCounter, colors); foreach (HighlightDescriptor hd in mHighlightDescriptors) { if (!colors.ContainsKey(hd.Color)) { AddColorToTable(sb, hd.Color, ref colorCounter, colors); } } // Parsing text sb.Append("}\n").Append(@"\viewkind4\uc1\pard\ltrpar"); SetDefaultSettings(sb, colors, fonts); char[] sperators = mSeperators.GetAsCharArray(); // Replacing "\" to "\\" for RTF... string[] lines = Text.Replace("\\", "\\\\").Replace("{", "\\{").Replace("}", "\\}").Split('\n'); for (int lineCounter = 0; lineCounter < lines.Length; lineCounter++) { if (lineCounter != 0) { AddNewLine(sb); } string line = lines[lineCounter]; string[] tokens = mCaseSesitive ? line.Split(sperators) : line.ToUpper().Split(sperators); if (tokens.Length == 0) { sb.Append(line); AddNewLine(sb); continue; } int tokenCounter = 0; for (int i = 0; i < line.Length;) { char curChar = line[i]; if (mSeperators.Contains(curChar)) { sb.Append(curChar); i++; } else { string curToken = tokens[tokenCounter++]; bool bAddToken = true; foreach (HighlightDescriptor hd in mHighlightDescriptors) { string compareStr = mCaseSesitive ? hd.Token : hd.Token.ToUpper(); bool match = false; // Check if the highlight descriptor matches the current toker according to the DescriptoRecognision property. switch (hd.DescriptorRecognition) { case DescriptorRecognition.WholeWord: if (curToken == compareStr) { match = true; } break; case DescriptorRecognition.StartsWith: if (curToken.StartsWith(compareStr)) { match = true; } break; case DescriptorRecognition.Contains: if (curToken.IndexOf(compareStr) != -1) { match = true; } break; } if (!match) // If this token doesn't match chech the next one. { continue; } // printing this token will be handled by the inner code, don't apply default settings... bAddToken = false; // Set colors to current descriptor settings. SetDescriptorSettings(sb, hd, colors, fonts); // Print text affected by this descriptor. switch (hd.DescriptorType) { case DescriptorType.Word: sb.Append(line.Substring(i, curToken.Length)); SetDefaultSettings(sb, colors, fonts); i += curToken.Length; break; case DescriptorType.ToEOL: sb.Append(line.Remove(0, i)); i = line.Length; SetDefaultSettings(sb, colors, fonts); break; case DescriptorType.ToCloseToken: while ((line.IndexOf(hd.CloseToken, i) == -1) && (lineCounter < lines.Length)) { sb.Append(line.Remove(0, i)); lineCounter++; if (lineCounter < lines.Length) { AddNewLine(sb); line = lines[lineCounter]; i = 0; } else { i = line.Length; } } if (line.IndexOf(hd.CloseToken, i) != -1) { sb.Append(line.Substring(i, line.IndexOf(hd.CloseToken, i) + hd.CloseToken.Length - i)); line = line.Remove(0, line.IndexOf(hd.CloseToken, i) + hd.CloseToken.Length); tokenCounter = 0; tokens = mCaseSesitive ? line.Split(sperators) : line.ToUpper().Split(sperators); SetDefaultSettings(sb, colors, fonts); i = 0; } break; } break; } if (bAddToken) { // Print text with default settings... sb.Append(line.Substring(i, curToken.Length)); i += curToken.Length; } } } } // System.Diagnostics.Debug.WriteLine(sb.ToString()); Rtf = sb.ToString(); // Restore cursor and scrollbars location. SelectionStart = cursorLoc; mParsing = false; SetScrollPos(scrollPos); Win32.LockWindowUpdate((IntPtr)0); Invalidate(); if (mAutoCompleteShown) { if (mFilterAutoComplete) { SetAutoCompleteItems(); SetAutoCompleteSize(); SetAutoCompleteLocation(false); } SetBestSelectedAutoCompleteItem(); } }
/// <summary> /// Sends a win32 message to set scrollbars position. /// </summary> /// <param name="point">a POINT conatining H/Vscrollbar scrollpos.</param> private unsafe void SetScrollPos(Win32.POINT point) { IntPtr ptr = new IntPtr(&point); Win32.SendMessage(Handle, Win32.EM_SETSCROLLPOS, 0, ptr); }
public UndoRedoInfo(string text, Win32.POINT scrollPos, int cursorLoc) { Text = text; ScrollPos = scrollPos; CursorLocation = cursorLoc; }