#region Using Directives using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.IO; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Text; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using ScintillaNET.Configuration; using ScintillaNET.Design; using ScintillaNET.Properties; #endregion Using Directives namespace ScintillaNET { /// /// Represents a Scintilla text editor control. /// [Designer(typeof(ScintillaDesigner))] [Docking(DockingBehavior.Ask)] [DefaultBindingProperty("Text")] [DefaultProperty("Text")] [DefaultEvent("DocumentChanged")] public partial class Scintilla : Control, INativeScintilla, ISupportInitialize { #region Fields private static IntPtr _moduleHandle; private static string _moduleName = (IntPtr.Size == 4 ? Resources.ModuleName : Resources.ModuleName64); private static NativeMethods.Scintilla_DirectFunction _directFunction; private IntPtr _directPointer; private static readonly object _annotationChangedEventKey = new object(); private static readonly object _autoCompleteAcceptedEventKey = new object(); private static readonly object _beforeTextDeleteEventKey = new object(); private static readonly object _beforeTextInsertEventKey = new object(); private static readonly object _borderStyleChangedEventKey = new object(); private static readonly object _callTipClickEventKey = new object(); private static readonly object _charAddedEventKey = new object(); private static readonly object _documentChangeEventKey = new object(); private static readonly object _dropMarkerCollectEventKey = new object(); private static readonly object _dwellEndEventKey = new object(); private static readonly object _dwellStartEventKey = new object(); private static readonly object _foldChangedEventKey = new object(); private static readonly object _hotspotClickedEventKey = new object(); private static readonly object _hotspotDoubleClickedEventKey = new object(); private static readonly object _hotspotReleaseClickEventKey = new object(); private static readonly object _indicatorClickEventKey = new object(); private static readonly object _linesNeedShownEventKey = new object(); private static readonly object _loadEventKey = new object(); private static readonly object _macroRecordEventKey = new object(); private static readonly object _marginClickEventKey = new object(); private static readonly object _markerChangedEventKey = new object(); private static readonly object _modifiedChangedEventKey = new object(); private static readonly object _readOnlyModifyAttemptEventKey = new object(); private static readonly object _scrollEventKey = new object(); private static readonly object _selectionChangedEventKey = new object(); private static readonly object _styleNeededEventKey = new object(); private static readonly object _textDeletedEventKey = new object(); private static readonly object _textInsertedEventKey = new object(); private static readonly object _uriDroppedEventKey = new object(); private static readonly object _userListEventKey = new object(); private static readonly object _zoomChangedEventKey = new object(); private static readonly int _modifiedState = BitVector32.CreateMask(); private static readonly int _acceptsReturnState = BitVector32.CreateMask(_modifiedState); private static readonly int _acceptsTabState = BitVector32.CreateMask(_acceptsReturnState); private BitVector32 _state; private AnnotationCollection _annotations; private LineWrapping _lineWrapping; private List _helpers = new List(); private AutoComplete _autoComplete; private CallTip _callTip; private CaretInfo _caret; private Clipboard _clipboard; private Commands _commands; private Configuration.ConfigurationManager _configurationManager; private DocumentHandler _documentHandler; private DocumentNavigation _documentNavigation; private DropMarkers _dropMarkers; private Encoding _encoding; private EndOfLine _endOfLine; private FindReplace _findReplace; private Folding _folding; private GoTo _goto; private HotspotStyle _hotspotStyle; private Indentation _indentation; private IndicatorCollection _indicators; private Lexing _lexing; private LineCollection _lines; private LongLines _longLines; private MarginCollection _margins; private MarkerCollection _markers; private Printing _printing; private Scrolling _scrolling; private Selection _selection; private SnippetManager _snippets; private StyleCollection _styles; private UndoRedo _undoRedo; private Whitespace _whitespace; private bool _allowDrop; private string _caption; private Dictionary _colorBag = new Dictionary(); /// /// Enables the brace matching from current position. /// private bool _isBraceMatching = false; private bool _isCustomPaintingEnabled = true; private bool _isInitializing = false; private List _managedRanges = new List(); private bool _matchBraces = true; private INativeScintilla _ns; private Hashtable _propertyBag = new Hashtable(); private SearchFlags _searchFlags = SearchFlags.Empty; private bool _supressControlCharacters = true; // List of Scintilla Supported encodings internal static readonly IList ValidCodePages = new Encoding[] { Encoding.ASCII, Encoding.UTF8, Encoding.Unicode, // UTF-16 Encoding.GetEncoding(932), // shift_jis - Japanese (Shift-JIS) Encoding.GetEncoding(936), // gb2312 - Chinese Simplified (GB2312) Encoding.GetEncoding(949), // ks_c_5601-1987 - Korean Encoding.GetEncoding(950), // big5 - Chinese Traditional (Big5) Encoding.GetEncoding(1361) // Johab - Korean (Johab) }; // This has to be set *early* because CreateParams is called before our constructor private BorderStyle _borderStyle = BorderStyle.Fixed3D; private VisualStyleRenderer _renderer; #endregion Fields #region Methods /// /// Adds a line _end marker to the _end of the document /// public void AddLastLineEnd() { EndOfLineMode eolMode = _endOfLine.Mode; string eolMarker = "\r\n"; if (eolMode == EndOfLineMode.CR) eolMarker = "\r"; else if (eolMode == EndOfLineMode.LF) eolMarker = "\n"; int tl = TextLength; int start = tl - eolMarker.Length; if (start < 0 || GetRange(start, start + eolMarker.Length).Text != eolMarker) AppendText(eolMarker); } /// /// Appends a copy of the specified string to the _end of this instance. /// /// The to append. /// A representing the appended text. public Range AppendText(string text) { int oldLength = TextLength; NativeInterface.AppendText(Encoding.GetByteCount(text), text); return GetRange(oldLength, TextLength); } public void BeginInit() { _isInitializing = true; } public char CharAt(int position) { return _ns.GetCharAt(position); } /// /// Creates and returns a new object. /// /// A new object. [EditorBrowsable(EditorBrowsableState.Advanced)] protected virtual AnnotationCollection CreateAnnotationsInstance() { return new AnnotationCollection(this); } /// /// Creates and returns a new object. /// /// A new object. [EditorBrowsable(EditorBrowsableState.Advanced)] protected virtual LineWrapping CreateLineWrappingInstance() { return new LineWrapping(this); } /// /// Sends the specified message directly to the native Scintilla window, /// bypassing any managed APIs. /// /// The message ID. /// The message wparam field. /// The message lparam field. /// An representing the result of the message request. /// /// Warning: The Surgeon General Has Determined that Calling the Underlying Scintilla /// Window Directly May Result in Unexpected Behavior! /// /// /// The method was called from a thread other than the thread it was created on. /// [EditorBrowsable(EditorBrowsableState.Advanced)] public IntPtr DirectMessage(int msg, IntPtr wParam, IntPtr lParam) { // Enforce illegal cross-thread calls if (Form.CheckForIllegalCrossThreadCalls && InvokeRequired) { string message = string.Format(Resources.Culture, Resources.Exception_IllegalCrossThreadCall, Name); throw new InvalidOperationException(message); } // Call the direct function delegate return _directFunction(_directPointer, msg, wParam, lParam); } /// /// Overridden. Releases the unmanaged resources used by the and /// its child controls and optionally releases the managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool disposing) { foreach (ScintillaHelperBase heler in _helpers) { heler.Dispose(); } if (disposing && IsHandleCreated) { // wi11811 2008-07-28 Chris Rickard // Since we eat the destroy message in WndProc // we have to manually let Scintilla know to // clean up its resources. Message destroyMessage = new Message(); destroyMessage.Msg = NativeMethods.WM_DESTROY; destroyMessage.HWnd = Handle; base.DefWndProc(ref destroyMessage); } base.Dispose(disposing); } public void EndInit() { _isInitializing = false; foreach (ScintillaHelperBase helper in _helpers) { helper.Initialize(); } } /// /// Exports a HTML representation of the current document. /// /// A containing the contents of the document formatted as HTML. /// Only ASCII documents are supported. Other encoding types have undefined behavior. public string ExportHtml() { StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) ExportHtml(sw, "Untitled", false); return sb.ToString(); } /// /// Exports a HTML representation of the current document. /// /// The with which to write. /// The title of the HTML document. /// /// true to output all styles including those not /// used in the document; otherwise, false. /// /// Only ASCII documents are supported. Other encoding types have undefined behavior. public void ExportHtml(TextWriter writer, string title, bool allStyles) { // Make sure the document is current // Lexing.Colorize(); // Get the styles used int length = NativeInterface.GetLength(); bool[] stylesUsed = new bool[(int)StylesCommon.Max + 1]; if (allStyles) { for (int i = 0; i < stylesUsed.Length; i++) stylesUsed[i] = true; } else { // Record all the styles used for (int i = 0; i < length; i++) stylesUsed[Styles.GetStyleAt(i) & (int)StylesCommon.Max] = true; } // The tab width int tabWidth = Indentation.TabWidth; // Start writing writer.WriteLine(@""); writer.WriteLine(""); writer.WriteLine(""); writer.WriteLine("{0}", title); writer.WriteLine(@""); writer.WriteLine(""); writer.WriteLine(""); // Write the document // TODO There's more to be done here to support codepages/UTF-8 char lc; char c = '\0'; int lastStyle = -1; for (int i = 0; i < length; i++) { lc = c; c = NativeInterface.GetCharAt(i); int style = Styles.GetStyleAt(i); if(style != lastStyle) { if(lastStyle != -1) writer.Write(""); writer.Write(@"", style); lastStyle = style; } switch (c) { case '\0': continue; case ' ': if (lc == ' ') writer.Write(" "); else writer.Write(c); continue; case '\t': for (int t = 0; t < tabWidth; t++) writer.Write("  "); continue; case '\r': case '\n': if (c == '\r' && i < length - 1 && NativeInterface.GetCharAt(i + 1) == '\n') i++; if (lastStyle != -1) writer.Write(""); writer.WriteLine("
"); lastStyle = -1; continue; case '<': writer.Write("<"); continue; case '>': writer.Write(">"); continue; case '&': writer.Write("&"); continue; default: writer.Write(c); continue; } } if (lastStyle != -1) writer.Write(""); writer.WriteLine(); writer.WriteLine(""); writer.WriteLine(""); } public int FindColumn(int line, int column) { return _ns.FindColumn(line, column); } internal void FireCallTipClick(int arrow) { CallTipArrow a = (CallTipArrow)arrow; OverloadList ol = CallTip.OverloadList; CallTipClickEventArgs e; if (ol == null) { e = new CallTipClickEventArgs(a, -1, -1, null, CallTip.HighlightStart, CallTip.HighlightEnd); } else { int newIndex = ol.CurrentIndex; if (a == CallTipArrow.Down) { if (ol.CurrentIndex == ol.Count - 1) newIndex = 0; else newIndex++; } else if (a == CallTipArrow.Up) { if (ol.CurrentIndex == 0) newIndex = ol.Count - 1; else newIndex--; } e = new CallTipClickEventArgs(a, ol.CurrentIndex, newIndex, ol, CallTip.HighlightStart, CallTip.HighlightEnd); } OnCallTipClick(e); if (e.Cancel) { CallTip.Cancel(); } else { if (ol != null) { // We allow them to alse replace the list entirely or just // manipulate the New Index CallTip.OverloadList = e.OverloadList; CallTip.OverloadList.CurrentIndex = e.NewIndex; CallTip.ShowOverloadInternal(); } } } internal void FireKeyDown(KeyEventArgs e) { OnKeyDown(e); } internal void FireMarginClick(SCNotification n) { Margin m = Margins[n.margin]; Keys k = Keys.None; if ((n.modifiers & (int)KeyMod.Alt) == (int)KeyMod.Alt) k |= Keys.Alt; if ((n.modifiers & (int)KeyMod.Ctrl) == (int)KeyMod.Ctrl) k |= Keys.Control; if ((n.modifiers & (int)KeyMod.Shift) == (int)KeyMod.Shift) k |= Keys.Shift; OnMarginClick(new MarginClickEventArgs(k, n.position, Lines.FromPosition(n.position), m, m.AutoToggleMarkerNumber, m.IsFoldMargin)); } public int GetColumn(int position) { return _ns.GetColumn(position); } /// /// Gets the text of the line containing the caret. /// /// A representing the text of the line containing the caret. public unsafe string GetCurrentLine() { int tmp; return GetCurrentLine(out tmp); } /// /// Gets the text of the line containing the caret and the current caret position within that line. /// /// When this method returns, contains the byte offset of the current caret position with the line. /// A representing the text of the line containing the caret. public unsafe string GetCurrentLine(out int caretPosition) { int length = DirectMessage(NativeMethods.SCI_GETCURLINE, IntPtr.Zero, IntPtr.Zero).ToInt32(); byte[] buffer = new byte[length]; fixed (byte* bp = buffer) caretPosition = DirectMessage(NativeMethods.SCI_GETCURLINE, new IntPtr(buffer.Length), new IntPtr(bp)).ToInt32(); return Encoding.GetString(buffer, 0, length - 1); } public Range GetRange() { return new Range(0, _ns.GetTextLength(), this); } public Range GetRange(int position) { return new Range(position, position + 1, this); } public Range GetRange(int startPosition, int endPosition) { return new Range(startPosition, endPosition, this); } /// /// Gets a word from the specified position /// public string GetWordFromPosition(int position) { // Chris Rickard 2008-07-28 // Fixing implementation to actually return the word at the position... // Credit goes to Stumpii for the code. // As a side note: I think the previous code was implemented based off // some funky code I made for the snippet keyword detection, but since // it doesn't reference this method there's no reason to keep the buggy // behavior. I also removed the try..catch because in theory this // shouldn't throw and we REALLY shouldn't be eating exceptions at the // System.Exception level. If some _start popping up I can add some // conditionals or catch more specific Exceptions. int startPosition = NativeInterface.WordStartPosition(position, true); int endPosition = NativeInterface.WordEndPosition(position, true); return GetRange(startPosition, endPosition).Text; } /// /// Inserts text at the current cursor position /// /// Text to insert /// The range inserted public Range InsertText(string text) { NativeInterface.AddText(Encoding.GetByteCount(text), text); return GetRange(_caret.Position, Encoding.GetByteCount(text)); } /// /// Inserts text at the given position /// /// The position to insert text in /// Text to insert /// The text range inserted public Range InsertText(int position, string text) { NativeInterface.InsertText(position, text); return GetRange(position, Encoding.GetByteCount(text)); } /// /// Overridden. See . /// protected override bool IsInputKey(Keys keyData) { if ((keyData & Keys.Shift) != Keys.None) keyData ^= Keys.Shift; switch (keyData) { case Keys.Tab: return _state[_acceptsTabState]; case Keys.Enter: return _state[_acceptsReturnState]; case Keys.Up: case Keys.Down: case Keys.Left: case Keys.Right: case Keys.F: return true; } return base.IsInputKey(keyData); } private static void LoadModule() { if (_moduleHandle == IntPtr.Zero) { // Load the Scintilla module into memory if ((_moduleHandle = NativeMethods.LoadLibrary(_moduleName)) == IntPtr.Zero) { string message = string.Format(Resources.Culture, Resources.Exception_CannotLoadModule, _moduleName); throw new Win32Exception(message, new Win32Exception(Marshal.GetLastWin32Error())); } // Get the direct function. We use GetProcAddress instead of DllImport // because we don't know the name of the module ahead of time. _directFunction = Marshal.GetDelegateForFunctionPointer( NativeMethods.GetProcAddress(_moduleHandle, "Scintilla_DirectFunction"), typeof(NativeMethods.Scintilla_DirectFunction)) as NativeMethods.Scintilla_DirectFunction; if (_directFunction == null) { string message = string.Format(Resources.Culture, Resources.Exception_InvalidModule, _moduleName); throw new Win32Exception(message, new Win32Exception(Marshal.GetLastWin32Error())); } } } private List ManagedRangesInRange(int firstPos, int lastPos) { // TODO: look into optimizing this so that it isn't a linear // search. This is fine for a few markers per document but // can be greatly improved if there are a large # of markers List ret = new List(); foreach (ManagedRange mr in _managedRanges) if (mr.Start >= firstPos && mr.Start <= lastPos) ret.Add(mr); return ret; } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnAnnotationChanged(AnnotationChangedEventArgs e) { EventHandler handler = Events[_annotationChangedEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnAutoCompleteAccepted(AutoCompleteAcceptedEventArgs e) { EventHandler handler = Events[_autoCompleteAcceptedEventKey] as EventHandler; if (handler != null) handler(this, e); if (e.Cancel) AutoComplete.Cancel(); } /// /// Raises the event. /// /// An that contains the event data. protected override void OnBackColorChanged(EventArgs e) { ResetStyles(); base.OnBackColorChanged(e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnBeforeTextDelete(TextModifiedEventArgs e) { int firstPos = e.Position; int lastPos = firstPos + e.Length; List deletedRanges = new List(); foreach (ManagedRange mr in _managedRanges) { // These ranges lie within the deleted range so // the ranges themselves need to be deleted if (mr.Start >= firstPos && mr.End <= lastPos) { // If the entire range is being delete and NOT a superset of the range, // don't delete it, only collapse it. if (!mr.IsPoint && e.Position == mr.Start && (e.Position + e.Length == mr.End)) { mr.Change(mr.Start, mr.Start); } else { // Notify the virtual Range that it needs to cleanup mr.Change(-1, -1); // Mark for deletion after this foreach: deletedRanges.Add(mr); } } else if (mr.Start >= lastPos) { // These ranges are merely offset by the deleted range mr.Change(mr.Start - e.Length, mr.End - e.Length); } else if (mr.Start >= firstPos && mr.Start <= lastPos) { // The left side of the managed range is getting // cut off mr.Change(firstPos, mr.End - e.Length); } else if (mr.Start < firstPos && mr.End >= firstPos && mr.End >= lastPos) { mr.Change(mr.Start, mr.End - e.Length); } else if (mr.Start < firstPos && mr.End >= firstPos && mr.End < lastPos) { mr.Change(mr.Start, firstPos); } } foreach (ManagedRange mr in deletedRanges) mr.Dispose(); EventHandler handler = Events[_beforeTextDeleteEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnBeforeTextInsert(TextModifiedEventArgs e) { List offsetRanges = new List(); foreach (ManagedRange mr in _managedRanges) { if (mr.Start == e.Position && mr.PendingDeletion) { mr.PendingDeletion = false; ManagedRange lmr = mr; BeginInvoke(new MethodInvoker(delegate() { lmr.Change(e.Position, e.Position + e.Length); })); } // If the Range is a single point we treat it slightly // differently than a spanned range if (mr.IsPoint) { // Unlike a spanned range, if the insertion point of // the new text == the _start of the range (and thus // the _end as well) we offset the entire point. if (mr.Start >= e.Position) mr.Change(mr.Start + e.Length, mr.End + e.Length); else if (mr.End >= e.Position) mr.Change(mr.Start, mr.End + e.Length); } else { // We offset a spanned range entirely only if the // _start occurs after the insertion point of the new // text. if (mr.Start > e.Position) mr.Change(mr.Start + e.Length, mr.End + e.Length); else if (mr.End >= e.Position) { // However it the _start of the range == the insertion // point of the new text instead of offestting the // range we expand it. mr.Change(mr.Start, mr.End + e.Length); } } } EventHandler handler = Events[_beforeTextInsertEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnBorderStyleChanged(EventArgs e) { EventHandler handler = Events[_borderStyleChangedEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnCallTipClick(CallTipClickEventArgs e) { EventHandler handler = Events[_callTipClickEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnCharAdded(CharAddedEventArgs e) { EventHandler handler = Events[_charAddedEventKey] as EventHandler; if (handler != null) handler(this, e); if (_indentation.SmartIndentType != SmartIndent.None) _indentation.CheckSmartIndent(e.Ch); } /// /// Overridden. See . /// protected override void OnCreateControl() { base.OnCreateControl(); OnLoad(EventArgs.Empty); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnDocumentChange(NativeScintillaEventArgs e) { EventHandler handler = Events[_documentChangeEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Provides the support for code block selection /// protected override void OnDoubleClick(EventArgs e) { base.OnDoubleClick(e); if (_isBraceMatching) { int position = CurrentPos - 1, bracePosStart = -1, bracePosEnd = -1; char character = (char)CharAt(position); switch (character) { case '{': case '(': case '[': if (!this.PositionIsOnComment(position)) { bracePosStart = position; bracePosEnd = _ns.BraceMatch(position, 0) + 1; _selection.Start = bracePosStart; _selection.End = bracePosEnd; } break; } } } /// /// Raises the event. /// /// An that contains the event data. protected internal virtual void OnDropMarkerCollect(DropMarkerCollectEventArgs e) { EventHandler handler = Events[_dropMarkerCollectEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnDwellEnd(ScintillaMouseEventArgs e) { EventHandler handler = Events[_dwellEndEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnDwellStart(ScintillaMouseEventArgs e) { EventHandler handler = Events[_dwellStartEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnFoldChanged(FoldChangedEventArgs e) { EventHandler handler = Events[_foldChangedEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected override void OnFontChanged(EventArgs e) { ResetStyles(); base.OnFontChanged(e); } /// /// Raises the event. /// /// An that contains the event data. protected override void OnForeColorChanged(EventArgs e) { ResetStyles(); base.OnForeColorChanged(e); } /// /// Overridden. See . /// protected override void OnGotFocus(EventArgs e) { if (!Selection.Hidden) _ns.HideSelection(false); _ns.SetSelBack(Selection.BackColor != Color.Transparent, Utilities.ColorToRgb(Selection.BackColor)); _ns.SetSelFore(Selection.ForeColor != Color.Transparent, Utilities.ColorToRgb(Selection.ForeColor)); base.OnGotFocus(e); } /// /// Overridden. Raises the event. /// /// An that contains the event data. protected override void OnHandleCreated(EventArgs e) { // The Scintilla native control kindly registers itself as a target of OLE drag-and-drop operations, // however, that prevents us from doing the same. Unregistering it prior to calling base.OnHandleCreated // will re-register us according to the AllowDrop property and we'll get support for the Drag events. if (IsHandleCreated) NativeMethods.RevokeDragDrop(Handle); // Get the Scintilla direct pointer _directPointer = NativeMethods.SendMessage(Handle, NativeMethods.SCI_GETDIRECTPOINTER, IntPtr.Zero, IntPtr.Zero); if (_directPointer == IntPtr.Zero) throw new Win32Exception(Resources.Exception_CannotCreateDirectFunction); base.OnHandleCreated(e); } /// /// Raises the event. /// /// A that contains the event data. protected virtual void OnHotspotClick(HotspotClickEventArgs e) { EventHandler handler = Events[_hotspotClickEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// A that contains the event data. protected virtual void OnHotspotDoubleClick(HotspotClickEventArgs e) { EventHandler handler = Events[_hotspotDoubleClickEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// A that contains the event data. protected virtual void OnHotspotReleaseClick(HotspotClickEventArgs e) { EventHandler handler = Events[_hotspotReleaseClickEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnIndicatorClick(ScintillaMouseEventArgs e) { EventHandler handler = Events[_indicatorClickEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Overridden. See . /// protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (!e.Handled) e.SuppressKeyPress = _commands.ProcessKey(e); } /// /// Overridden. See . /// protected override void OnKeyPress(KeyPressEventArgs e) { if (_supressControlCharacters && (int)e.KeyChar < 32) e.Handled = true; if (_snippets.IsEnabled && _snippets.IsOneKeySelectionEmbedEnabled && _selection.Length > 0) { Snippet s; if (_snippets.List.TryGetValue(e.KeyChar.ToString(), out s)) { if (s.IsSurroundsWith) { _snippets.InsertSnippet(s); e.Handled = true; } } } base.OnKeyPress(e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnLinesNeedShown(LinesNeedShownEventArgs e) { EventHandler handler = Events[_linesNeedShownEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnLoad(EventArgs e) { EventHandler handler = Events[_loadEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Overridden. See . /// protected override void OnLostFocus(EventArgs e) { if (Selection.HideSelection) _ns.HideSelection(true); _ns.SetSelBack(Selection.BackColorUnfocused != Color.Transparent, Utilities.ColorToRgb(Selection.BackColorUnfocused)); _ns.SetSelFore(Selection.ForeColorUnfocused != Color.Transparent, Utilities.ColorToRgb(Selection.ForeColorUnfocused)); base.OnLostFocus(e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnMacroRecord(MacroRecordEventArgs e) { EventHandler handler = Events[_macroRecordEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnMarginClick(MarginClickEventArgs e) { EventHandler handler = Events[_marginClickEventKey] as EventHandler; if (handler != null) handler(this, e); if (e.ToggleMarkerNumber >= 0) { int mask = (int)Math.Pow(2, e.ToggleMarkerNumber); if ((e.Line.GetMarkerMask() & mask) == mask) e.Line.DeleteMarker(e.ToggleMarkerNumber); else e.Line.AddMarker(e.ToggleMarkerNumber); } if (e.ToggleFold) e.Line.ToggleFoldExpanded(); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnMarkerChanged(MarkerChangedEventArgs e) { EventHandler handler = Events[_markerChangedEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnModifiedChanged(EventArgs e) { EventHandler handler = Events[_modifiedChangedEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Overridden. See . /// protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); paintRanges(e.Graphics); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnReadOnlyModifyAttempt(EventArgs e) { EventHandler handler = Events[_readOnlyModifyAttemptEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnScroll(ScrollEventArgs e) { EventHandler handler = Events[_scrollEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnSelectionChanged(EventArgs e) { //this is being fired in tandem with the cursor blink... EventHandler handler = Events[_selectionChangedEventKey] as EventHandler; if (handler != null) handler(this, e); if (_isBraceMatching && (_selection.Length == 0)) { int position = CurrentPos - 1, bracePosStart = -1, bracePosEnd = -1; char character = (char)CharAt(position); switch (character) { case '{': case '}': case '(': case ')': case '[': case ']': if (!this.PositionIsOnComment(position)) { bracePosStart = position; bracePosEnd = _ns.BraceMatch(position,0); if(bracePosEnd >= 0) { _ns.BraceHighlight(bracePosStart, bracePosEnd); } else { _ns.BraceBadLight(bracePosStart); } } break; default: position = CurrentPos; character = (char)CharAt(position); //this is not being used anywhere... --Cory _ns.BraceHighlight(bracePosStart, bracePosEnd); break; } } } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnStyleNeeded(StyleNeededEventArgs e) { EventHandler handler = Events[_styleNeededEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnTextDeleted(TextModifiedEventArgs e) { EventHandler handler = Events[_textDeletedEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnTextInserted(TextModifiedEventArgs e) { EventHandler handler = Events[_textInsertedEventKey] as EventHandler; if (handler != null) handler(this, e); } /// /// Raises the event. /// /// An that contains the event data. protected virtual void OnZoomChanged(EventArgs e) { EventHandler handler = Events[_zoomChangedEventKey] as EventHandler; if (handler != null) handler(this, e); } private void paintRanges(Graphics g) { // First we want to get the range (in positions) of what // will be painted so that we know which markers to paint int firstLine = Lines.FirstVisibleIndex; int lastLine = firstLine + _ns.LinesOnScreen(); int firstPos = _ns.PositionFromLine(firstLine); int lastPos = _ns.PositionFromLine(lastLine + 1) - 1; // If the lastLine was outside the defined document range it will // contain -1, defualt it to the last doc position if (lastPos < 0) lastPos = _ns.GetLength(); List mrs = ManagedRangesInRange(firstPos, lastPos); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; foreach (ManagedRange mr in mrs) { mr.Paint(g); } } public int PointXFromPosition(int position) { return _ns.PointXFromPosition(position); } public int PointYFromPosition(int position) { return _ns.PointYFromPosition(position); } public int PositionFromPoint(int x, int y) { return _ns.PositionFromPoint(x, y); } public int PositionFromPointClose(int x, int y) { return _ns.PositionFromPointClose(x, y); } /// /// Checks that if the specified position is on comment. /// public bool PositionIsOnComment(int position) { //this.Colorize(0, -1); return PositionIsOnComment(position, _lexing.Lexer); } /// /// Checks that if the specified position is on comment. /// public bool PositionIsOnComment(int position, Lexer lexer) { int style = _styles.GetStyleAt(position); if ((lexer == Lexer.Python || lexer == Lexer.Lisp) && (style == 1 || style == 12)) { return true; // python or lisp } else if ((lexer == Lexer.Cpp || lexer == Lexer.Pascal || lexer == Lexer.Tcl || lexer == Lexer.Bullant) && (style == 1 || style == 2 || style == 3 || style == 15 || style == 17 || style == 18)) { return true; // cpp, tcl, bullant or pascal } else if ((lexer == Lexer.Hypertext || lexer == Lexer.Xml) && (style == 9 || style == 20 || style == 29 || style == 30 || style == 42 || style == 43 || style == 44 || style == 57 || style == 58 || style == 59 || style == 72 || style == 82 || style == 92 || style == 107 || style == 124 || style == 125)) { return true; // html or xml } else if ((lexer == Lexer.Perl || lexer == Lexer.Ruby || lexer == Lexer.Clw || lexer == Lexer.Bash) && style == 2) { return true; // perl, bash, clarion/clw or ruby } else if ((lexer == Lexer.Sql) && (style == 1 || style == 2 || style == 3 || style == 13 || style == 15 || style == 17 || style == 18)) { return true; // sql } else if ((lexer == Lexer.VB || lexer == Lexer.Properties || lexer == Lexer.MakeFile || lexer == Lexer.Batch || lexer == Lexer.Diff || lexer == Lexer.Conf || lexer == Lexer.Ave || lexer == Lexer.Eiffel || lexer == Lexer.EiffelKw || lexer == Lexer.Tcl || lexer == Lexer.VBScript || lexer == Lexer.MatLab || lexer == Lexer.Fortran || lexer == Lexer.F77 || lexer == Lexer.Lout || lexer == Lexer.Mmixal || lexer == Lexer.Yaml || lexer == Lexer.PowerBasic || lexer == Lexer.ErLang || lexer == Lexer.Octave || lexer == Lexer.Kix || lexer == Lexer.Asn1) && style == 1) { return true; // asn1, vb, diff, batch, makefile, avenue, eiffel, eiffelkw, vbscript, matlab, crontab, fortran, f77, lout, mmixal, yaml, powerbasic, erlang, octave, kix or properties } else if ((lexer == Lexer.Latex) && style == 4) { return true; // latex } else if ((lexer == Lexer.Lua || lexer == Lexer.EScript || lexer == Lexer.Verilog) && (style == 1 || style == 2 || style == 3)) { return true; // lua, verilog or escript } else if ((lexer == Lexer.Ada) && style == 10) { return true; // ada } else if ((lexer == Lexer.Baan || lexer == Lexer.Pov || lexer == Lexer.Ps || lexer == Lexer.Forth || lexer == Lexer.MsSql || lexer == Lexer.Gui4Cli || lexer == Lexer.Au3 || lexer == Lexer.Apdl || lexer == Lexer.Vhdl || lexer == Lexer.Rebol) && (style == 1 || style == 2)) { return true; // au3, apdl, baan, ps, mssql, rebol, forth, gui4cli, vhdl or pov } else if ((lexer == Lexer.Asm) && (style == 1 || style == 11)) { return true; // asm } else if ((lexer == Lexer.Nsis) && (style == 1 || style == 18)) { return true; // nsis } else if ((lexer == Lexer.Specman) && (style == 2 || style == 3)) { return true; // specman } else if ((lexer == Lexer.Tads3) && (style == 3 || style == 4)) { return true; // tads3 } else if ((lexer == Lexer.CSound) && (style == 1 || style == 9)) { return true; // csound } else if ((lexer == Lexer.Caml) && (style == 12 || style == 13 || style == 14 || style == 15)) { return true; // caml } else if ((lexer == Lexer.Haskell) && (style == 13 || style == 14 || style == 15 || style == 16)) { return true; // haskell } else if ((lexer == Lexer.Flagship) && (style == 1 || style == 2 || style == 3 || style == 4 || style == 5 || style == 6)) { return true; // flagship } else if ((lexer == Lexer.Smalltalk) && style == 3) { return true; // smalltalk } else if ((lexer == Lexer.Css) && style == 9) { return true; // css } return false; } /// /// Overridden. See . /// protected override bool ProcessKeyMessage(ref Message m) { // For some reason IsInputKey isn't working for // Key.Enter. This seems to make it work as expected if ((int)m.WParam == (int)Keys.Enter && !AcceptsReturn) { return true; } else { return base.ProcessKeyMessage(ref m); } } private void ResetCaption() { Caption = GetType().FullName; } private void ResetMargins() { _margins.Reset(); } private void ResetStyles() { // One of the core appearance properties has changed. When this happens // we restyle the document (overriding any existing styling) in the core // appearance properties. This behavior is consistent with the RichTextBox. NativeInterface.StartStyling(0, 0x7F); NativeInterface.SetStyling(NativeInterface.GetLength(), 0); Styles[0].Reset(); Styles[0].Font = Font; Styles[0].ForeColor = ForeColor; Styles[0].BackColor = BackColor; Styles.Default.BackColor = BackColor; } /// /// Custom way to find the matching brace when BraceMatch() does not work /// internal int SafeBraceMatch(int position) { int match = this.CharAt(position); int toMatch = 0; int length = TextLength; int ch; int sub = 0; Lexer lexer = _lexing.Lexer; _lexing.Colorize(0, -1); bool comment = PositionIsOnComment(position, lexer); switch (match) { case '{': toMatch = '}'; goto down; case '(': toMatch = ')'; goto down; case '[': toMatch = ']'; goto down; case '}': toMatch = '{'; goto up; case ')': toMatch = '('; goto up; case ']': toMatch = '['; goto up; } return -1; // search up up: while (position >= 0) { position--; ch = CharAt(position); if (ch == match) { if (comment == PositionIsOnComment(position, lexer)) sub++; } else if (ch == toMatch && comment == PositionIsOnComment(position, lexer)) { sub--; if (sub < 0) return position; } } return -1; // search down down: while (position < length) { position++; ch = CharAt(position); if (ch == match) { if (comment == PositionIsOnComment(position, lexer)) sub++; } else if (ch == toMatch && comment == PositionIsOnComment(position, lexer)) { sub--; if (sub < 0) return position; } } return -1; } private void ScnModified(ref NativeMethods.SCNotification scn) { if ((scn.modificationType & NativeMethods.SC_MOD_CHANGEANNOTATION) == NativeMethods.SC_MOD_CHANGEANNOTATION) { AnnotationChangedEventArgs acea = new AnnotationChangedEventArgs(scn.line, scn.annotationLinesAdded); OnAnnotationChanged(acea); } } /// /// Sets the application-wide default module name of the native Scintilla library. /// /// The native Scintilla module name. /// This method must be called prior to the first control being created. /// The is null. /// The is an empty string. /// This method was called after the first control was created. public static void SetModuleName(string moduleName) { const string paramName = "moduleName"; if (moduleName == null) throw new ArgumentNullException(paramName); if (moduleName.Length == 0) throw new ArgumentException(string.Format(Resources.Culture, Resources.Exception_EmptyStringArgument, paramName), paramName); if (_moduleHandle != IntPtr.Zero) throw new InvalidOperationException(Resources.Exception_ModuleAlreadyLoaded); _moduleName = moduleName; } private bool SetRenderer(VisualStyleElement element) { if (!Application.RenderWithVisualStyles) return false; if (!VisualStyleRenderer.IsElementDefined(element)) return false; if (_renderer == null) _renderer = new VisualStyleRenderer(element); else _renderer.SetParameters(element); return true; } private bool ShouldSerializeAnnotations() { return _annotations != null && _annotations.ShouldSerialize(); } private bool ShouldSerializeAutoComplete() { return _autoComplete.ShouldSerialize(); } private bool ShouldSerializeCallTip() { return _callTip.ShouldSerialize(); } private bool ShouldSerializeCaption() { return Caption != GetType().FullName; } private bool ShouldSerializeCaret() { return _caret.ShouldSerialize(); } private bool ShouldSerializeClipboard() { return _clipboard.ShouldSerialize(); } private bool ShouldSerializeCommands() { return _commands.ShouldSerialize(); } private bool ShouldSerializeConfigurationManager() { return _configurationManager.ShouldSerialize(); } private bool ShouldSerializeDocumentNavigation() { return _documentNavigation.ShouldSerialize(); } private bool ShouldSerializeDropMarkers() { return _dropMarkers.ShouldSerialize(); } private bool ShouldSerializeEndOfLine() { return _endOfLine.ShouldSerialize(); } private bool ShouldSerializeFindReplace() { return _findReplace.ShouldSerialize(); } private bool ShouldSerializeFolding() { return _folding.ShouldSerialize(); } private bool ShouldSerializeHotspotStyle() { return _hotspotStyle.ShouldSerialize(); } private bool ShouldSerializeIndentation() { return _indentation.ShouldSerialize(); } private bool ShouldSerializeLexing() { return _lexing.ShouldSerialize(); } private bool ShouldSerializeLineWrapping() { return LineWrapping.ShouldSerialize(); } private bool ShouldSerializeLongLines() { return _longLines.ShouldSerialize(); } private bool ShouldSerializeMargins() { return _margins.ShouldSerialize(); } private bool ShouldSerializeMarkers() { return _markers.ShouldSerialize(); } private bool ShouldSerializePrinting() { return _printing.ShouldSerialize(); } private bool ShouldSerializeScrolling() { return _scrolling.ShouldSerialize(); } private bool ShouldSerializeSelection() { return _selection.ShouldSerialize(); } private bool ShouldSerializeSnippets() { return _snippets.ShouldSerialize(); } private bool ShouldSerializeStyles() { return _styles.ShouldSerialize(); } public bool ShouldSerializeUndoRedo() { return _undoRedo.ShouldSerialize(); } private void WmNcPaint(ref Message m) { // We only paint when border is 3D if (BorderStyle != BorderStyle.Fixed3D) { base.WndProc(ref m); return; } // Configure the renderer VisualStyleElement element = VisualStyleElement.TextBox.TextEdit.Normal; /*if (!Enabled) element = VisualStyleElement.TextBox.TextEdit.Disabled; else*/ if (IsReadOnly) element = VisualStyleElement.TextBox.TextEdit.ReadOnly; else if (Focused) element = VisualStyleElement.TextBox.TextEdit.Focused; if (!SetRenderer(element)) { base.WndProc(ref m); return; } NativeMethods.RECT windowRect; NativeMethods.GetWindowRect(m.HWnd, out windowRect); Size borderSize = SystemInformation.Border3DSize; IntPtr hDC = NativeMethods.GetWindowDC(m.HWnd); try { using (Graphics graphics = Graphics.FromHdc(hDC)) { // Clip everything except the border Rectangle bounds = new Rectangle(0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top); graphics.ExcludeClip(Rectangle.Inflate(bounds, -borderSize.Width, -borderSize.Height)); // Paint the theme border if (_renderer.IsBackgroundPartiallyTransparent()) _renderer.DrawParentBackground(graphics, bounds, this); _renderer.DrawBackground(graphics, bounds); } } finally { NativeMethods.ReleaseDC(m.HWnd, hDC); } // Create a new region to pass to the default proc that excludes our border IntPtr clipRegion = NativeMethods.CreateRectRgn( windowRect.left + borderSize.Width, windowRect.top + borderSize.Height, windowRect.right - borderSize.Width, windowRect.bottom - borderSize.Height); if (m.WParam != (IntPtr)1) NativeMethods.CombineRgn(clipRegion, clipRegion, m.WParam, NativeMethods.RGN_AND); // Call default proc to get the scrollbars, etc... painted m.WParam = clipRegion; DefWndProc(ref m); m.Result = IntPtr.Zero; } private void WmReflectCommand(ref Message m) { switch(Utilities.SignedHiWord(m.WParam)) { case NativeMethods.SCEN_CHANGE: // TODO It looks like TextChanged is firing twice for every change. // This appears to be a Scintilla behavior, not us, but we might be able to work around it. OnTextChanged(EventArgs.Empty); break; default: base.WndProc(ref m); break; } } private void WmReflectNotify(ref Message m) { // New *internal* structure... NativeMethods.SCNotification scn = (NativeMethods.SCNotification)Marshal.PtrToStructure(m.LParam, typeof(NativeMethods.SCNotification)); // Old *public* *outdated* structure and event args... SCNotification scnOld = (SCNotification)Marshal.PtrToStructure(m.LParam, typeof(SCNotification)); NativeScintillaEventArgs nsea = new NativeScintillaEventArgs(m, scnOld); switch (scnOld.nmhdr.code) { case Constants.SCN_AUTOCSELECTION: FireAutoCSelection(nsea); break; case Constants.SCN_CALLTIPCLICK: FireCallTipClick(nsea); break; case Constants.SCN_CHARADDED: FireCharAdded(nsea); break; case Constants.SCN_DOUBLECLICK: FireDoubleClick(nsea); break; case Constants.SCN_DWELLEND: FireDwellEnd(nsea); break; case Constants.SCN_DWELLSTART: FireDwellStart(nsea); break; case NativeMethods.SCN_HOTSPOTCLICK: OnHotspotClick(new HotspotClickEventArgs(scn.position)); break; case NativeMethods.SCN_HOTSPOTDOUBLECLICK: OnHotspotDoubleClick(new HotspotClickEventArgs(scn.position)); break; case NativeMethods.SCN_HOTSPOTRELEASECLICK: OnHotspotReleaseClick(new HotspotClickEventArgs(scn.position)); break; case Constants.SCN_INDICATORCLICK: FireIndicatorClick(nsea); break; case Constants.SCN_INDICATORRELEASE: FireIndicatorRelease(nsea); break; case Constants.SCN_KEY: FireKey(nsea); break; case Constants.SCN_MACRORECORD: FireMacroRecord(nsea); break; case Constants.SCN_MARGINCLICK: FireMarginClick(nsea); break; case Constants.SCN_MODIFIED: ScnModified(ref scn); FireModified(nsea); break; case Constants.SCN_MODIFYATTEMPTRO: FireModifyAttemptRO(nsea); break; case Constants.SCN_NEEDSHOWN: FireNeedShown(nsea); break; case Constants.SCN_PAINTED: FirePainted(nsea); break; case Constants.SCN_SAVEPOINTLEFT: FireSavePointLeft(nsea); break; case Constants.SCN_SAVEPOINTREACHED: FireSavePointReached(nsea); break; case Constants.SCN_STYLENEEDED: FireStyleNeeded(nsea); break; case Constants.SCN_UPDATEUI: FireUpdateUI(nsea); break; case Constants.SCN_URIDROPPED: FireUriDropped(nsea); break; case Constants.SCN_USERLISTSELECTION: FireUserListSelection(nsea); break; case Constants.SCN_ZOOM: FireZoom(nsea); break; } } private void WmScroll(ref Message m) { ScrollOrientation so = ScrollOrientation.VerticalScroll; int oldScroll = 0, newScroll = 0; ScrollEventType set = (ScrollEventType)(Utilities.SignedLoWord(m.WParam)); if (m.Msg == NativeMethods.WM_HSCROLL) { so = ScrollOrientation.HorizontalScroll; oldScroll = _ns.GetXOffset(); // Let Scintilla Handle the scroll Message to actually perform scrolling base.WndProc(ref m); newScroll = _ns.GetXOffset(); } else { so = ScrollOrientation.VerticalScroll; oldScroll = Lines.FirstVisibleIndex; base.WndProc(ref m); newScroll = Lines.FirstVisibleIndex; } OnScroll(new ScrollEventArgs(set, oldScroll, newScroll, so)); } /// /// Overridden. Processes Windows messages. /// /// The Windows to process. protected override void WndProc(ref Message m) { switch (m.Msg) { case NativeMethods.WM_DESTROY: // wi11811 2008-07-28 Chris Rickard // If we get a destroy message we make this window a message-only window so that it doesn't actually // get destroyed, causing Scintilla to wipe out all its settings associated with this window handle. // We do send a WM_DESTROY message to Scintilla in the Dispose() method so that it does clean up its // resources when this control is actually done with. Credit (blame :) goes to tom103 for figuring // this one out. if (this.IsHandleCreated) { NativeMethods.SetParent(this.Handle, NativeMethods.HWND_MESSAGE); return; } base.WndProc(ref m); break; case NativeMethods.WM_NCPAINT: WmNcPaint(ref m); break; case NativeMethods.WM_PAINT: // I tried toggling the ControlStyles.UserPaint flag and sending the message // to both base.WndProc and DefWndProc in order to get the best of both worlds, // Scintilla Paints as normal and .NET fires the Paint Event with the proper // clipping regions and such. This didn't work too well, I kept getting weird // phantom paints, or sometimes the .NET paint events would seem to get painted // over by Scintilla. This technique I use below seems to work perfectly. base.WndProc(ref m); if (_isCustomPaintingEnabled) { ScintillaNET.RECT r; if (!NativeMethods.GetUpdateRect(Handle, out r, false)) r = ClientRectangle; using (Graphics g = CreateGraphics()) { g.SetClip(r); OnPaint(new PaintEventArgs(g, r)); } } break; case NativeMethods.WM_SETCURSOR: base.DefWndProc(ref m); break; case NativeMethods.WM_GETTEXT: m.WParam = (IntPtr)(Caption.Length + 1); Marshal.Copy(Caption.ToCharArray(), 0, m.LParam, Caption.Length); m.Result = (IntPtr)Caption.Length; break; case NativeMethods.WM_GETTEXTLENGTH: m.Result = (IntPtr)Caption.Length; break; case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFY: WmReflectNotify(ref m); break; case NativeMethods.WM_REFLECT + NativeMethods.WM_COMMAND: WmReflectCommand(ref m); break; case NativeMethods.WM_HSCROLL: case NativeMethods.WM_VSCROLL: WmScroll(ref m); break; default: if ((int)m.Msg >= 10000) // TODO Remove "magic number" { _commands.Execute((BindableCommand)m.Msg); return; } base.WndProc(ref m); break; } } public void ZoomIn() { _ns.ZoomIn(); } private void ZoomOut() { _ns.ZoomOut(); } #endregion Methods #region Properties /// /// Gets or sets a value indicating whether pressing ENTER creates a new line of text in the /// control or activates the default button for the form. /// /// /// true if the ENTER key creates a new line of text; false if the ENTER key activates /// the default button for the form. The default is false. /// [DefaultValue(true), Category("Behavior")] [Description("Indicates if return characters are accepted as text input.")] public bool AcceptsReturn { get { return _state[_acceptsReturnState]; } set { _state[_acceptsReturnState] = value; } } /// /// Gets or sets a value indicating whether pressing the TAB key types a TAB character in the control /// instead of moving the focus to the next control in the tab order. /// /// /// true if users can enter tabs using the TAB key; false if pressing the TAB key /// moves the focus. The default is false. /// [DefaultValue(true), Category("Behavior")] [Description("Indicates if tab characters are accepted as text input.")] public bool AcceptsTab { get { return _state[_acceptsTabState]; } set { _state[_acceptsTabState] = value; } } /// /// Gets a collection containing all annotations in the control. /// /// /// A that contains all the annotations in the control. /// [Category("Appearance")] [Description("The annotations and options.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public AnnotationCollection Annotations { get { if (_annotations == null) _annotations = CreateAnnotationsInstance(); return _annotations; } } /// /// Controls autocompletion behavior. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public AutoComplete AutoComplete { get { return _autoComplete; } } /// /// Gets or sets the background color for the control. /// /// /// A that represents the background color of the control. /// The default is . /// /// Settings this property resets any current document styling. [DefaultValue(typeof(Color), "Window")] public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; } } /// /// This property is not relevant for this class. /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override Image BackgroundImage { get { return base.BackgroundImage; } set { base.BackgroundImage = value; } } /// /// This property is not relevant for this class. /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public override ImageLayout BackgroundImageLayout { get { return base.BackgroundImageLayout; } set { base.BackgroundImageLayout = value; } } /// /// Gets or sets the border style of the control. /// /// /// A that represents the border type of the control. /// The default is . /// /// /// The value assigned is not one of the values. /// [DefaultValue(BorderStyle.Fixed3D), Category("Appearance")] [Description("Indicates whether the control should have a border.")] // TODO Move to a resource public BorderStyle BorderStyle { get { return _borderStyle; } set { if (!Enum.IsDefined(typeof(BorderStyle), value)) throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle)); if (value != _borderStyle) { _borderStyle = value; // This will cause the CreateParams to be reapplied UpdateStyles(); OnBorderStyleChanged(EventArgs.Empty); } } } /// /// Manages CallTip (Visual Studio-like code Tooltip) behaviors /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public CallTip CallTip { get { return _callTip; } set { _callTip = value; } } /// /// Gets/Sets the Win32 Window Caption. Defaults to Type's FullName /// [Category("Behavior")] [Description("Win32 Window Caption")] public string Caption { get { return _caption; } set { if (_caption != value) { _caption = value; // Triggers a new WM_GETTEXT query base.Text = value; } } } /// /// Controls Caret Behavior /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Appearance")] public CaretInfo Caret { get { return _caret; } } /// /// Gets Clipboard access for the control. /// /// A object the provides Clipboard access for the control. [Category("Behavior")] // TODO Place in resource file [Description("Clipboard (cut, copy, paste) options.")] // TODO Place in resource file [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public Clipboard Clipboard { get { return _clipboard; } } internal Dictionary ColorBag { get { return _colorBag; } } /// /// Controls behavior of keyboard bound commands. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public Commands Commands { get { return _commands; } set { _commands = value; } } /// /// Controls behavior of loading/managing ScintillaNET configurations. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public Configuration.ConfigurationManager ConfigurationManager { get { return _configurationManager; } set { _configurationManager = value; } } /// /// Overridden. See . /// protected override CreateParams CreateParams { [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { // Otherwise Scintilla won't paint. When UserPaint is set to // true the base Class (Control) eats the WM_PAINT message. // Of course when this set to false we can't use the Paint // events. This is why I'm relying on the Paint notification // sent from scintilla to paint the Marker Arrows. SetStyle(ControlStyles.UserPaint, false); // I hope the old man got that tractor beam out if commission, // or this is going to be a real short trip. Okay, hit it! LoadModule(); // Tell Windows Forms to create a Scintilla // derived Window Class for this control CreateParams cp = base.CreateParams; cp.ClassName = "Scintilla"; // Set the window style or extended style // to the appropriate border type. switch (_borderStyle) { case BorderStyle.Fixed3D: cp.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE; cp.Style &= ~NativeMethods.WS_BORDER; break; case BorderStyle.FixedSingle: cp.ExStyle &= ~NativeMethods.WS_EX_CLIENTEDGE; cp.Style |= NativeMethods.WS_BORDER; break; default: cp.ExStyle &= ~NativeMethods.WS_EX_CLIENTEDGE; cp.Style &= ~NativeMethods.WS_BORDER; break; } return cp; } } /// /// Gets or sets the character index of the current caret position. /// /// The character index of the current caret position. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int CurrentPos { get { return NativeInterface.GetCurrentPos(); } set { NativeInterface.GotoPos(value); } } /// Gets or sets the default cursor for the control. /// An object of type representing the current default cursor. protected override Cursor DefaultCursor { get { return Cursors.IBeam; } } /// /// Overridden. See . /// protected override Size DefaultSize { get { return new Size(200, 100); } } /// /// Controls behavior of Documents /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public DocumentHandler DocumentHandler { get { return _documentHandler; } set { _documentHandler = value; } } /// /// Controls behavior of automatic document navigation /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public DocumentNavigation DocumentNavigation { get { return _documentNavigation; } set { _documentNavigation = value; } } /// /// Controls behavior of Drop Markers /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public DropMarkers DropMarkers { get { return _dropMarkers; } } /// /// Controls Encoding behavior /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Encoding Encoding { get { return _encoding; } set { // EncoderFallbackException isn't really the correct exception but // I'm being lazy and you get the point if (!ValidCodePages.Contains(value)) throw new EncoderFallbackException("Scintilla only supports the following Encodings: " + ValidCodePages.ToString()); _encoding = value; _ns.SetCodePage(_encoding.CodePage); } } /// /// Controls End Of Line Behavior /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public EndOfLine EndOfLine { get { return _endOfLine; } set { _endOfLine = value; } } [Category("Behavior")] public FindReplace FindReplace { get { return _findReplace; } set { _findReplace = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public Folding Folding { get { return _folding; } set { _folding = value; } } /// /// Gets or sets the font of the text displayed by the control. /// /// /// The to apply to the text displayed by the control. /// The default is the value of the property. /// /// Settings this property resets any current document styling. public override Font Font { get { return base.Font; } set { base.Font = value; } } /// /// Gets or sets the foreground color of the control. /// /// /// The foreground of the control. /// The default is . /// /// Settings this property resets any current document styling. [DefaultValue(typeof(Color), "WindowText")] public override Color ForeColor { get { return base.ForeColor; } set { base.ForeColor = value; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GoTo GoTo { get { return _goto; } set { _goto = value; } } protected internal List Helpers { get { return _helpers; } set { _helpers = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Appearance")] public HotspotStyle HotspotStyle { get { return _hotspotStyle; } set { _hotspotStyle = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public Indentation Indentation { get { return _indentation; } set { _indentation = value; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IndicatorCollection Indicators { get { return _indicators; } } [DefaultValue(false), Category("Behavior")] public bool IsBraceMatching { get { return _isBraceMatching; } set { _isBraceMatching = value; } } [DefaultValue(true), Category("Behavior")] public bool IsCustomPaintingEnabled { get { return _isCustomPaintingEnabled; } set { _isCustomPaintingEnabled = value; } } internal bool IsDesignMode { get { return DesignMode; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] internal bool IsInitializing { get { return _isInitializing; } set { _isInitializing = value; } } [DefaultValue(false), Category("Behavior")] public bool IsReadOnly { get { return _ns.GetReadOnly(); } set { _ns.SetReadOnly(value); } } /// /// Gets or sets the line layout caching strategy in a control. /// /// /// One of the enumeration values. /// The default is . /// /// /// The value assigned is not one of the values. /// /// Larger cache sizes increase performance at the expense of memory. [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Advanced)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public LayoutCacheMode LayoutCacheMode { get { return (LayoutCacheMode)DirectMessage(NativeMethods.SCI_GETLAYOUTCACHE, IntPtr.Zero, IntPtr.Zero); } set { if (!Enum.IsDefined(typeof(LayoutCacheMode), value)) throw new InvalidEnumArgumentException("value", (int)value, typeof(LayoutCacheMode)); DirectMessage(NativeMethods.SCI_SETLAYOUTCACHE, new IntPtr((int)value), IntPtr.Zero); } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public Lexing Lexing { get { return _lexing; } set { _lexing = value; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public LineCollection Lines { get { return _lines; } } /// /// Gets an object that controls line wrapping options in the control. /// /// A object that manages line wrapping options in a control. [Category("Behavior")] // TODO Move to resource file [Description("The control's line wrapping options.")] // TODO Move to resource file [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public LineWrapping LineWrapping { get { if (_lineWrapping == null) _lineWrapping = CreateLineWrappingInstance(); return _lineWrapping; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public LongLines LongLines { get { return _longLines; } set { _longLines = value; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public List ManagedRanges { get { return _managedRanges; } } [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Appearance")] public MarginCollection Margins { get { return _margins; } } /// /// Gets a collection representing the marker objects and options within the control. /// /// A representing the marker objects and options within the control. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public MarkerCollection Markers { get { return _markers; } set { _markers = value; } } [DefaultValue(true), Category("Behavior")] public bool MatchBraces { get { return _matchBraces; } set { _matchBraces = value; // Clear any active Brace matching that may exist if (!value) _ns.BraceHighlight(-1, -1); } } /// /// Gets or sets a value that indicates that the control has been modified by the user since /// the control was created or its contents were last set. /// /// /// true if the control's contents have been modified; otherwise, false. /// The default is false. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool Modified { get { return _state[_modifiedState]; } set { if (_state[_modifiedState] != value) { // Update the local (and native) state _state[_modifiedState] = value; if (!value) _ns.SetSavePoint(); OnModifiedChanged(EventArgs.Empty); } } } [DefaultValue(true), Category("Behavior")] public bool MouseDownCaptures { get { return NativeInterface.GetMouseDownCaptures(); } set { NativeInterface.SetMouseDownCaptures(value); } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public INativeScintilla NativeInterface { get { return this as INativeScintilla; } } [DefaultValue(false), Category("Behavior")] public bool OverType { get { return _ns.GetOvertype(); } set { _ns.SetOvertype(value); } } /// /// Gets or sets the position cache size used to layout short runs of text in a control. /// /// The size of the position cache in bytes. The default is 1024. /// Larger cache sizes increase performance at the expense of memory. [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Advanced)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual int PositionCacheSize { get { return DirectMessage(NativeMethods.SCI_GETPOSITIONCACHE, IntPtr.Zero, IntPtr.Zero).ToInt32(); } set { // TODO Some range checking? Scintilla provides no guidance DirectMessage(NativeMethods.SCI_SETPOSITIONCACHE, new IntPtr(value), IntPtr.Zero); } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Layout")] public Printing Printing { get { return _printing; } set { _printing = value; } } internal Hashtable PropertyBag { get { return _propertyBag; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] unsafe public byte[] RawText { get { int length = NativeInterface.GetTextLength() + 1; // May as well avoid all the crap below if we know what the outcome // is going to be :) if (length == 1) return new byte[] { 0 }; // Allocate a buffer the size of the string + 1 for // the NULL terminator. Scintilla always sets this // regardless of the encoding byte[] buffer = new byte[length]; // Get a direct pointer to the the head of the buffer // to pass to the message along with the wParam. // Scintilla will fill the buffer with string data. fixed (byte* bp = buffer) { _ns.SendMessageDirect(Constants.SCI_GETTEXT, (IntPtr)length, (IntPtr)bp); return buffer; } } set { if (value == null || value.Length == 0) { _ns.ClearAll(); } else { // This byte[] HAS to be NULL terminated or who knows how big // of an overrun we'll have on our hands if (value[value.Length - 1] != 0) { // I hate to have to do this becuase it can be very inefficient. // It can probably be done much better by the client app Array.Resize(ref value, value.Length + 1); value[value.Length - 1] = 0; } fixed (byte* bp = value) _ns.SendMessageDirect(Constants.SCI_SETTEXT, IntPtr.Zero, (IntPtr)bp); } } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Layout")] public Scrolling Scrolling { get { return _scrolling; } set { _scrolling = value; } } [DefaultValue(SearchFlags.Empty), Category("Behavior")] [Editor(typeof(Design.FlagEnumUIEditor), typeof(System.Drawing.Design.UITypeEditor))] public SearchFlags SearchFlags { get { return _searchFlags; } set { _searchFlags = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Appearance")] public Selection Selection { get { return _selection; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public SnippetManager Snippets { get { return _snippets; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Appearance")] public StyleCollection Styles { get { return _styles; } set { _styles = value; } } /// /// Gets or sets a value indicating whether characters not considered alphanumeric (ASCII values 0 through 31) /// are prevented as text input. /// /// /// true to prevent control characters as input; otherwise, false. /// The default is true. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool SupressControlCharacters { get { return _supressControlCharacters; } set { _supressControlCharacters = value; } } /// /// Gets or sets the current text in the control. /// /// The text displayed in the control. [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design", typeof(UITypeEditor))] public override string Text { get { string s; _ns.GetText(_ns.GetLength() + 1, out s); return s; } set { if (string.IsNullOrEmpty(value)) _ns.ClearAll(); else _ns.SetText(value); } } /// /// Gets the _length of text in the control. /// /// The number of characters contained in the text of the control. [Browsable(false)] public int TextLength { get { return NativeInterface.GetTextLength(); } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior")] public UndoRedo UndoRedo { get { return _undoRedo; } } public new bool UseWaitCursor { get { return base.UseWaitCursor; } set { base.UseWaitCursor = value; if (value) NativeInterface.SetCursor(Constants.SC_CURSORWAIT); else NativeInterface.SetCursor(Constants.SC_CURSORNORMAL); } } /// /// Gets the display mode and style behavior associated with the control. /// /// A object that represents whitespace display mode and style behavior in a control. [Category("Appearance"), Description("The display mode and style of whitespace characters.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public Whitespace Whitespace { get { return _whitespace; } } /// /// Gets or sets the current zoom level of the control. /// /// The factor by which the contents of the control is zoomed. [DefaultValue(0), Category("Appearance")] [Description("Defines the current scaling factor of the text display; 0 is normal viewing.")] public int Zoom { get { return _ns.GetZoom(); } set { _ns.SetZoom(value); } } #endregion Properties #region Events /// /// Occurs when an annotation has changed. /// [Category("Scintilla")] // TODO Move to resource [Description("Occurs when an annotation has changed.")] // TODO Move to resource public event EventHandler AnnotationChanged { add { Events.AddHandler(_annotationChangedEventKey, value); } remove { Events.RemoveHandler(_annotationChangedEventKey, value); } } /// /// Occurs when the user makes a selection from the auto-complete list. /// [Category("Scintilla"), Description("Occurs when the user makes a selection from the auto-complete list.")] public event EventHandler AutoCompleteAccepted { add { Events.AddHandler(_autoCompleteAcceptedEventKey, value); } remove { Events.RemoveHandler(_autoCompleteAcceptedEventKey, value); } } /// /// Occurs when text is about to be removed from the document. /// [Category("Scintilla"), Description("Occurs when text is about to be removed from the document.")] public event EventHandler BeforeTextDelete { add { Events.AddHandler(_beforeTextDeleteEventKey, value); } remove { Events.RemoveHandler(_beforeTextDeleteEventKey, value); } } /// /// Occurs when text is about to be inserted into the document. /// [Category("Scintilla"), Description("Occurs when text is about to be inserted into the document.")] public event EventHandler BeforeTextInsert { add { Events.AddHandler(_beforeTextInsertEventKey, value); } remove { Events.RemoveHandler(_beforeTextInsertEventKey, value); } } /// /// Occurs when the value of the property has changed. /// [Category("Property Changed")] [Description("Occurs when the value of the BorderStyle property changes.")] // TODO Move to resource public event EventHandler BorderStyleChanged { add { Events.AddHandler(_borderStyleChangedEventKey, value); } remove { Events.RemoveHandler(_borderStyleChangedEventKey, value); } } /// /// Occurs when a user clicks on a call tip. /// [Category("Scintilla"), Description("Occurs when a user clicks on a call tip.")] public event EventHandler CallTipClick { add { Events.AddHandler(_callTipClickEventKey, value); } remove { Events.RemoveHandler(_callTipClickEventKey, value); } } /// /// Occurs when the user types an ordinary text character (as opposed to a command character) into the text. /// [Category("Scintilla"), Description("Occurs when the user types a text character.")] public event EventHandler CharAdded { add { Events.AddHandler(_charAddedEventKey, value); } remove { Events.RemoveHandler(_charAddedEventKey, value); } } /// /// Occurs when the text or styling of the document changes or is about to change. /// [Category("Scintilla"), Description("Occurs when the text or styling of the document changes or is about to change.")] public event EventHandler DocumentChange { add { Events.AddHandler(_documentChangeEventKey, value); } remove { Events.RemoveHandler(_documentChangeEventKey, value); } } /// /// Occurs when a is about to be collected. /// [Category("Scintilla"), Description("Occurs when a DropMarker is about to be collected.")] public event EventHandler DropMarkerCollect { add { Events.AddHandler(_dropMarkerCollectEventKey, value); } remove { Events.RemoveHandler(_dropMarkerCollectEventKey, value); } } /// /// Occurs when a user actions such as a mouse move or key press ends a dwell (hover) activity. /// [Category("Scintilla"), Description("Occurs when a dwell (hover) activity has ended.")] public event EventHandler DwellEnd { add { Events.AddHandler(_dwellEndEventKey, value); } remove { Events.RemoveHandler(_dwellEndEventKey, value); } } /// /// Occurs when the user hovers the mouse (dwells) in one position for the dwell period. /// [Category("Scintilla"), Description("Occurs when the user hovers the mouse (dwells) in one position for the dwell period.")] public event EventHandler DwellStart { add { Events.AddHandler(_dwellStartEventKey, value); } remove { Events.RemoveHandler(_dwellStartEventKey, value); } } /// /// Occurs when a folding change has occurred. /// [Category("Scintilla"), Description("Occurs when a folding change has occurred.")] public event EventHandler FoldChanged { add { Events.AddHandler(_foldChangedEventKey, value); } remove { Events.RemoveHandler(_foldChangedEventKey, value); } } /// /// Occurs when a user clicks on text that is in a style with the hotspot attribute set. /// [Category("Scintilla")] [Description("Occurs when a user clicks on text with the hotspot style.")] // TODO Move to resource public event EventHandler HotspotClick { add { Events.AddHandler(_hotspotClickEventKey, value); } remove { Events.RemoveHandler(_hotspotClickEventKey, value); } } /// /// Occurs when a user double-clicks on text that is in a style with the hotspot attribute set. /// [Category("Scintilla")] [Description("Occurs when a user double-clicks on text with the hotspot style.")] // TODO Move to resource public event EventHandler HotspotDoubleClick { add { Events.AddHandler(_hotspotDoubleClickEventKey, value); } remove { Events.RemoveHandler(_hotspotDoubleClickEventKey, value); } } /// /// Occurs when a user releases a click on text that is in a style with the hotspot attribute set. /// [Category("Scintilla")] [Description("Occurs when a user releases a click on text with the hotspot style.")] // TODO Move to resource public event EventHandler HotspotReleaseClick { add { Events.AddHandler(_hotspotReleaseClickEventKey, value); } remove { Events.RemoveHandler(_hotspotReleaseClickEventKey, value); } } /// /// Occurs when the a clicks or releases the mouse on text that has an indicator. /// [Category("Scintilla"), Description("Occurs when the a clicks or releases the mouse on text that has an indicator.")] public event EventHandler IndicatorClick { add { Events.AddHandler(_indicatorClickEventKey, value); } remove { Events.RemoveHandler(_indicatorClickEventKey, value); } } /// /// Occurs when a range of lines that is currently invisible should be made visible. /// [Category("Scintilla"), Description("Occurs when a range of lines that is currently invisible should be made visible.")] public event EventHandler LinesNeedShown { add { Events.AddHandler(_linesNeedShownEventKey, value); } remove { Events.RemoveHandler(_linesNeedShownEventKey, value); } } /// /// Occurs when the control is first loaded. /// [Category("Behavior"), Description("Occurs when the control is first loaded.")] public event EventHandler Load { add { Events.AddHandler(_loadEventKey, value); } remove { Events.RemoveHandler(_loadEventKey, value); } } /// /// Occurs each time a recordable change occurs. /// [Category("Scintilla"), Description("Occurs each time a recordable change occurs.")] public event EventHandler MacroRecord { add { Events.AddHandler(_macroRecordEventKey, value); } remove { Events.RemoveHandler(_macroRecordEventKey, value); } } /// /// Occurs when the mouse was clicked inside a margin that was marked as sensitive. /// [Category("Scintilla"), Description("Occurs when the mouse was clicked inside a margin that was marked as sensitive.")] public event EventHandler MarginClick { add { Events.AddHandler(_marginClickEventKey, value); } remove { Events.RemoveHandler(_marginClickEventKey, value); } } /// /// Occurs when one or more markers has changed in a line of text. /// [Category("Scintilla"), Description("Occurs when one or more markers has changed in a line of text.")] public event EventHandler MarkerChanged { add { Events.AddHandler(_markerChangedEventKey, value); } remove { Events.RemoveHandler(_markerChangedEventKey, value); } } /// /// Occurs when the value of the property has changed. /// [Category("Property Changed"), Description("Occurs when the value of the Modified property changes.")] public event EventHandler ModifiedChanged { add { Events.AddHandler(_modifiedChangedEventKey, value); } remove { Events.RemoveHandler(_modifiedChangedEventKey, value); } } /// /// Occurs when a user tries to modify text when in read-only mode. /// [Category("Scintilla"), Description("Occurs when a user tries to modifiy text when in read-only mode.")] public event EventHandler ReadOnlyModifyAttempt { add { Events.AddHandler(_readOnlyModifyAttemptEventKey, value); } remove { Events.RemoveHandler(_readOnlyModifyAttemptEventKey, value); } } /// /// Occurs when the control is scrolled. /// [Category("Action"), Description("Occurs when the control is scrolled.")] public event EventHandler Scroll { add { Events.AddHandler(_scrollEventKey, value); } remove { Events.RemoveHandler(_scrollEventKey, value); } } /// /// Occurs when the selection has changed. /// [Category("Scintilla"), Description("Occurs when the selection has changed.")] public event EventHandler SelectionChanged { add { Events.AddHandler(_selectionChangedEventKey, value); } remove { Events.RemoveHandler(_selectionChangedEventKey, value); } } /// /// Occurs when the control is about to display or print text that requires styling. /// [Category("Scintilla"), Description("Occurs when the control is about to display or print text that requires styling.")] public event EventHandler StyleNeeded { add { Events.AddHandler(_styleNeededEventKey, value); } remove { Events.RemoveHandler(_styleNeededEventKey, value); } } /// /// Occurs when text has been removed from the document. /// [Category("Scintilla"), Description("Occurs when text has been removed from the document.")] public event EventHandler TextDeleted { add { Events.AddHandler(_textDeletedEventKey, value); } remove { Events.RemoveHandler(_textDeletedEventKey, value); } } /// /// Occurs when text has been inserted into the document. /// [Category("Scintilla"), Description("Occurs when text has been inserted into the document.")] public event EventHandler TextInserted { add { Events.AddHandler(_textInsertedEventKey, value); } remove { Events.RemoveHandler(_textInsertedEventKey, value); } } /// /// Occurs when the user zooms the display using the keyboard or the property is set. /// [Category("Scintilla"), Description("Occurs when the user zooms the display using the keyboard or the Zoom property is set.")] public event EventHandler ZoomChanged { add { Events.AddHandler(_zoomChangedEventKey, value); } remove { Events.RemoveHandler(_zoomChangedEventKey, value); } } #endregion Events #region Constructors public Scintilla() { this._state = new BitVector32(0); this._state[_acceptsReturnState] = true; this._state[_acceptsTabState] = true; _ns = (INativeScintilla)this; _caption = GetType().FullName; // Set up default encoding to UTF-8 which is the Scintilla's best supported. // .NET strings are UTF-16 but should be able to convert without any problems this.Encoding = Encoding.UTF8; // Ensure all style values have at least defaults _ns.StyleClearAll(); _caret = new CaretInfo(this); _lines = new LineCollection(this); _selection = new Selection(this); _indicators = new IndicatorCollection(this); _snippets = new SnippetManager(this); _margins = new MarginCollection(this); _scrolling = new Scrolling(this); _whitespace = new Whitespace(this); _endOfLine = new EndOfLine(this); _clipboard = new Clipboard(this); _undoRedo = new UndoRedo(this); _dropMarkers = new DropMarkers(this); _hotspotStyle = new HotspotStyle(this); _callTip = new CallTip(this); _styles = new StyleCollection(this); _indentation = new Indentation(this); _markers = new MarkerCollection(this); _autoComplete = new AutoComplete(this); _documentHandler = new DocumentHandler(this); _lexing = new Lexing(this); _longLines = new LongLines(this); _commands = new Commands(this); _folding = new Folding(this); _configurationManager = new ConfigurationManager(this); _printing = new Printing(this); _findReplace = new FindReplace(this); _documentNavigation = new DocumentNavigation(this); _goto = new GoTo(this); _helpers.AddRange(new TopLevelHelper[] { _caret, _lines, _selection, _indicators, _snippets, _margins, _scrolling, _whitespace, _endOfLine, _clipboard, _undoRedo, _dropMarkers, _hotspotStyle, _styles, _indentation, _markers, _autoComplete, _documentHandler, _lexing, _longLines, _commands, _folding, _configurationManager, _printing, _findReplace, _documentNavigation, _goto }); // Change from Scintilla's default black on white to // platform defaults for edit controls. base.BackColor = SystemColors.Window; base.ForeColor = SystemColors.WindowText; Styles[0].Font = Font; Styles[0].ForeColor = ForeColor; Styles[0].BackColor = BackColor; Styles.Default.BackColor = BackColor; } #endregion Constructors } }