其实有很强大的“ICSharpCode.TextEditor”。在此之前我一直使用的ICSharpCode.TextEditor。
不过在使用ICSharpCode.TextEditor的时候遇到了些问题,这里闲扯下。
好多年前我用它写了一个c#辅助的脚本工具,系统是win7的。后来重装系统之后这个程序就运行不起来,不得已更换了TextBox控件。当时也没有在意。
最近写一个程序需要用到该控件,在WIN10下程序都已完成。然后放到XP和WIN7中跑不起来,后来调试了很久才发现是ICSharpCode.TextEditor是这个控件的问题。
不知道大家有没有遇到问题,或者是我使用的不恰当。如没有遇到,或者解决的可否告知。毕竟我这个控件和ICSharpCode.TextEditor不管是功能和性能上差别太大。
无奈之下不得不屈服,重新写一个文本控件。
这里介绍一个“FastColoredTextBox”文本控件,很遗憾的是该控件不支持中文。
下面介绍下XZ.Edit文本编辑控件
源码地址:https://github.com/zzbjuke/eidtText
简单介绍下:
整个页面上显示的数据来源于重绘。
C#无法绘制光标,所以要调用WIN32 API
#region 调用WIN32API [DllImport("User32.dll")] static extern bool CreateCaret(IntPtr hWnd, int hBitmap, int nWidth, int nHeight); [DllImport("User32.dll")] static extern bool SetCaretPos(int x, int y); [DllImport("User32.dll")] static extern bool DestroyCaret(); [DllImport("User32.dll")] static extern bool ShowCaret(IntPtr hWnd); [DllImport("User32.dll")] static extern bool HideCaret(IntPtr hWnd); [DllImport("imm32.dll")] private static extern IntPtr ImmGetDefaultIMEWnd(IntPtr hWnd); [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, COMPOSITIONFORM lParam); [DllImport("Imm32.dll")] public static extern IntPtr ImmGetContext(IntPtr hWnd); [DllImport("Imm32.dll")] public static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC); #region 私有类 [StructLayout(LayoutKind.Sequential)] private class COMPOSITIONFORM { public int dwStyle = 0; public POINT ptCurrentPos = null; public RECT rcArea = null; } [StructLayout(LayoutKind.Sequential)] private class POINT { public int x = 0; public int y = 0; } [StructLayout(LayoutKind.Sequential)] private class RECT { public int left = 0; public int top = 0; public int right = 0; public int bottom = 0; } private void SetIMEWindowLocation(int x, int y) { if (pIMEWnd == IntPtr.Zero) return; POINT p = new POINT(); p.x = x; p.y = y; COMPOSITIONFORM lParam = new COMPOSITIONFORM(); lParam.dwStyle = CFS_POINT; lParam.ptCurrentPos = p; lParam.rcArea = new RECT(); try { SendMessage( pIMEWnd, WM_IME_CONTROL, new IntPtr(IMC_SETCOMPOSITIONWINDOW), lParam ); } catch (AccessViolationException ex) { MessageBox.Show("调用 IME: " + ex.Message); } } #endregion #endregion ////// 创建光标 /// /// /// ///public bool Create() { if (CreateCaret(this.pIEdit.GetHandle, 0, Width, FontContainer.FontHeight)) { this.Show(); return true; } return false; } /// /// 隐藏 /// public void Hide() { this.IsShowCurosr = false; HideCaret(this.pIEdit.GetHandle); } ////// 显示 /// public void Show() { this.IsShowCurosr = true; ShowCaret(this.pIEdit.GetHandle); } public void Dispose() { this.IsShowCurosr = false; DestroyCaret(); }
一定要重载WndProc 方法如下:
protected override void WndProc(ref Message m) { if (m.Msg == CharCommand.WM_HSCROLL || m.Msg == CharCommand.WM_VSCROLL) if (m.WParam.ToInt32() != CharCommand.SB_ENDSCROLL) Invalidate(); base.WndProc(ref m); if (ImeAllowed && m.Msg == CursorAndIME.WM_IME_SETCONTEXT && m.WParam.ToInt32() == 1) this.PCursor.CreateImmAssociateContext(); }
因本人空余时间编写的,时间有限。部分功能并未完成,且存在着某些BUG。
代码难度不大,就是啰嗦。
目前多行注释中仍然有注释,未完成待续。