Net文本编辑器,语法高亮,折叠,自动补全,提示

其实有很强大的“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

        /// <summary>
        /// 创建光标
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public bool Create() {
            if (CreateCaret(this.pIEdit.GetHandle, 0, Width, FontContainer.FontHeight)) {
                this.Show();
                return true;
            }
            return false;
        }    

        /// <summary>
        /// 隐藏
        /// </summary>
        public void Hide() {
            this.IsShowCurosr = false;
            HideCaret(this.pIEdit.GetHandle);
        }
        /// <summary>
        /// 显示
        /// </summary>
        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。

代码难度不大,就是啰嗦。

目前多行注释中仍然有注释,未完成待续。

 

posted @ 2017-12-28 10:40  juk  阅读(936)  评论(0编辑  收藏  举报