[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/lingsg/STTextBox/main/ST.Library.UI.STTextBox/STTextBox.cs [Back]  [Original]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;

namespace ST.Library.UI.STTextBox
{
    public partial class STTextBox : Control
    {
        [Browsable(false)]
        public float XDPIZoom { get; private set; }
        [Browsable(false)]
        public float YDPIZoom { get; private set; }

        private int _BorderWidth = 1;

        public int BorderWidth {
            get { return _BorderWidth; }
            set { _BorderWidth = value; }
        }

        private int _LineSpacing = 0;

        public int LineSpacing {
            get { return _LineSpacing; }
            set {
                if (value < 0) {
                    throw new ArgumentException("The value must be more than zero");
                }
                _LineSpacing = value;
                this.Invalidate();
            }
        }

        private int _CharSpacing = 0;

        public int CharSpacing {
            get { return _CharSpacing; }
            set {
                if (value < 0) {
                    throw new ArgumentException("The value must be more than zero");
                }
                _CharSpacing = value;
                this.Invalidate();
            }
        }

        private Color _BorderColor = Color.FromArgb(125, 0, 0, 0);

        public Color BorderColor {
            get { return _BorderColor; }
            set {
                if (_BorderColor == value) {
                    return;
                }
                _BorderColor = value;
                this.Invalidate();
            }
        }

        private Color _SelectionColor = Color.FromArgb(125, Color.DarkGray);

        public Color SelectionColor {
            get { return _SelectionColor; }
            set {
                if (value == _SelectionColor) {
                    return;
                }
                _SelectionColor = value;
                if (!m_core.Selection.IsEmptySelection) {
                    this.Invalidate();
                }
            }
        }

        private bool _AllowScrollBar = true;

        public bool AllowScrollBar {
            get { return _AllowScrollBar; }
            set { _AllowScrollBar = value; }
        }

        private Color _ScrollbarBackColor = Color.FromArgb(40, Color.Gray);

        public Color ScrollbarBackColor {
            get { return _ScrollbarBackColor; }
            set { _ScrollbarBackColor = value; }
        }

        private Color _ScrollBarCornerColor = Color.FromArgb(80, Color.Gray);

        public Color ScrollBarCornerColor {
            get { return _ScrollBarCornerColor; }
            set { _ScrollBarCornerColor = value; }
        }

        private Color _ScrollbarThumbHoverColor = Color.FromArgb(80, Color.Gray);

        public Color ScrollbarThumbHoverColor {
            get { return _ScrollbarThumbHoverColor; }
            set { _ScrollbarThumbHoverColor = value; }
        }

        private Color _ScrollbarThumbBackColor = Color.FromArgb(80, Color.Black);

        public Color ScrollbarThumbBackColor {
            get { return _ScrollbarThumbBackColor; }
            set { _ScrollbarThumbBackColor = value; }
        }

        private int _TabSize = 4;

        private bool _AutoIndent = true;

        private bool _TabToSpace = false;

        private const int WM_MOUSEHWHEEL = 0x020E;
        private object m_obj_sync = new object();
        private Timer m_timer;
        private IntPtr m_hIMC;
        protected Core m_core;


        public STTextBox() {
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            this.BackColor = Color.White;
            m_timer = new Timer();
            m_timer.Interval = 1000;
            m_timer.Tick += new EventHandler(m_timer_Tick);
            m_core = new Core(this);
        }

        #region override

        protected override void OnCreateControl() {
            base.OnCreateControl();
            using (Graphics g = this.CreateGraphics()) {
                this.XDPIZoom = g.DpiX / 96;
                this.YDPIZoom = g.DpiY / 96;
            }
        }

        protected override void WndProc(ref Message m) {
            switch (m.Msg) {
                case Win32.WM_IME_STARTCOMPOSITION:
                    m_hIMC = Win32.ImmGetContext(this.Handle);
                    this.OnImeStartPrivate(m_hIMC);
                    break;
                case Win32.WM_IME_ENDCOMPOSITION:
                    this.OnImeEndPrivate(m_hIMC);
                    break;
                case Win32.WM_IME_COMPOSITION:
                    if (((int)m.LParam & Win32.GCS_RESULTSTR) == Win32.GCS_RESULTSTR) {
                        m.Result = (IntPtr)1;
                        this.OnImeResultStrPrivate(m_hIMC, Win32.ImmGetCompositionString(m_hIMC, Win32.GCS_RESULTSTR));
                        return;//Interrupt, WM_CHAR, WM_IME_CHAR messages will not be generated.
                    }
                    if (((int)m.LParam & Win32.GCS_COMPSTR) == Win32.GCS_COMPSTR) {
                        this.OnImeCompStr(m_hIMC, Win32.ImmGetCompositionString(m_hIMC, Win32.GCS_COMPSTR));
                    }
                    break;
                case WM_MOUSEHWHEEL:
                    Point pt = new Point(((int)m.LParam) >> 16, (ushort)m.LParam);
                    pt = this.PointToClient(pt);
                    MouseButtons mb = MouseButtons.None;
                    int n = (ushort)m.WParam;
                    if ((n & 0x0001) == 0x0001) mb |= MouseButtons.Left;
                    if ((n & 0x0010) == 0x0010) mb |= MouseButtons.Middle;
                    if ((n & 0x0002) == 0x0002) mb |= MouseButtons.Right;
                    if ((n & 0x0020) == 0x0020) mb |= MouseButtons.XButton1;
                    if ((n & 0x0040) == 0x0040) mb |= MouseButtons.XButton2;
                    this.OnMouseHWheel(new MouseEventArgs(mb, 0, pt.X, pt.Y, ((int)m.WParam) >> 16));
                    break;
            }
            base.WndProc(ref m);
        }

        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
            //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            //sw.Start();
            this.XDPIZoom = e.Graphics.DpiX / 96;
            this.YDPIZoom = e.Graphics.DpiY / 96;
            var render = m_core.ITextBoxRender;
            //try {
            render.OnBeginPaint(e.Graphics);
            m_core.ITextView.OnDrawView(render);
            if (this._AllowScrollBar && m_core.Scroll.CountDown != 0) {
                this.OnCalcScrollRectangle(m_core.Scroll);
                bool bFlag = true;
                if (m_core.Scroll.HBackRect != m_core.Scroll.HThumbRect) {
                    this.OnDrawHScrollBar(render, m_core.Scroll);
                } else { bFlag = false; }
                if (m_core.Scroll.VBackRect != m_core.Scroll.VThumbRect) {
                    this.OnDrawVScrollBar(render, m_core.Scroll);
                } else { bFlag = false; }
                if (bFlag) this.OnDrawScrollBarCorner(render, m_core.Scroll);
            }
            this.OnDrawBorder(render);
            render.OnEndPaint(e.Graphics);
            //} catch (Exception ex) {
            //    MessageBox.Show(ex.Message + "\r\n\r\n" + ex.StackTrace);
            //}
            //sw.Stop();
            //Console.WriteLine("OnPaint - " + sw.ElapsedMilliseconds + "ms");
        }

        protected virtual void OnDrawBorder(ISTTextBoxRender render) {
            if (this._BorderWidth  scroll.HBackRect.Width) {
                rect_h_thumb.Width = scroll.HBackRect.Width;
            } else if (rect_h_thumb.Width < this.GetIntXSize(4)) {
                rect_h_thumb.Width = this.GetIntXSize(4);
            }

            fScale = ((float)rectV.Height / c.LineHeight) / (rectV.Height / c.LineHeight + scroll.MaxYValue);
            rect_v_thumb.Height = (int)(rectV.Height * fScale);
            if (rect_v_thumb.Height > scroll.VBackRect.Height) {
                rect_v_thumb.Height = scroll.VBackRect.Height;
            } else if (rect_v_thumb.Height < this.GetIntYSize(4)) {
                rect_v_thumb.Height = this.GetIntYSize(4);
            }

            rect_h_thumb.X = rectV.X;
            if (scroll.MaxXValue > 0) {
                fScale = (float)scroll.XValue / scroll.MaxXValue;
                rect_h_thumb.X += (int)((scroll.HBackRect.Width - rect_h_thumb.Width) * fScale);
            }

            rect_v_thumb.Y = rectV.Y;
            if (scroll.MaxYValue > 0) {
                fScale = (float)scroll.YValue / scroll.MaxYValue;
                rect_v_thumb.Y += (int)((scroll.VBackRect.Height - rect_v_thumb.Height) * fScale);
            }
            scroll.HThumbRect = rect_h_thumb;
            scroll.VThumbRect = rect_v_thumb;
            if (scroll.VBackRect == rect_v_thumb) {
                rect_h_thumb.Width += nSW;
                scroll.HThumbRect = rect_h_thumb;
                var temp = scroll.HBackRect;
                temp.Width += nSW;
                scroll.HBackRect = temp;
            } else if (scroll.HBackRect == rect_h_thumb) {
                rect_v_thumb.Height += nSH;
                scroll.VThumbRect = rect_v_thumb;
                var temp = scroll.VBackRect;
                temp.Height += nSH;
                scroll.VBackRect = temp;
            } else {
            }
            //scroll.HThumbRect = rect_h_thumb;
            //scroll.VThumbRect = rect_v_thumb;
        }

        protected virtual void OnDrawVScrollBar(ISTTextBoxRender render, STTextBoxScrollInfo scroll) {
            var clr = scroll.HoverScrollBar == STTextBoxScrollInfo.ScrollBarType.V ? this._ScrollbarThumbHoverColor : this._ScrollbarBackColor;
            render.FillRectangle(clr, scroll.VBackRect);
            render.FillRectangle(clr, scroll.VBackRect.X, scroll.VBackRect.Y, this.GetIntXSize(1), scroll.VBackRect.Height);
            render.FillRectangle(this._ScrollbarThumbBackColor, scroll.VThumbRect);
        }

        protected virtual void OnDrawHScrollBar(ISTTextBoxRender render, STTextBoxScrollInfo scroll) {
            var clr = scroll.HoverScrollBar == STTextBoxScrollInfo.ScrollBarType.H ? this._ScrollbarThumbHoverColor : this._ScrollbarBackColor;
            render.FillRectangle(clr, scroll.HBackRect);
            render.FillRectangle(clr, scroll.HBackRect.X, scroll.HBackRect.Y, scroll.HBackRect.Width, this.GetIntYSize(1));
            render.FillRectangle(this._ScrollbarThumbBackColor, scroll.HThumbRect);
        }

        protected virtual void OnDrawScrollBarCorner(ISTTextBoxRender render, STTextBoxScrollInfo scroll) {
            int nWidth = this.GetIntXSize(scroll.Size);
            int nHeight = this.GetIntYSize(scroll.Size);
            render.FillRectangle(
                this._ScrollBarCornerColor, m_core.ViewRectangle.Right - nWidth,
                m_core.ViewRectangle.Bottom - nHeight,
                nWidth,
                nHeight);
        }

        #endregion

        #region private

        private bool SetCursor(Cursor c) {
            if (this.Cursor == c) {
                return false;
            }
            this.Cursor = c;
            return true;
        }

        private void OnImeStartPrivate(IntPtr hIMC) {
            var CandidateForm = new Win32.CANDIDATEFORM() {
                dwStyle = Win32.CFS_CANDIDATEPOS,
                ptCurrentPos = m_core.Caret.Location
            };
            Win32.ImmSetCandidateWindow(hIMC, ref CandidateForm);

            var CompositionForm = new Win32.COMPOSITIONFORM() {
                dwStyle = Win32.CFS_FORCE_POSITION,
                ptCurrentPos = m_core.Caret.Location
            };
            Win32.ImmSetCompositionWindow(hIMC, ref CompositionForm);
            var logFont = new Win32.LOGFONT() {
                lfHeight = m_core.FontHeight,
                lfFaceName = this.Font.Name + "\0"
            };
            Win32.ImmSetCompositionFont(hIMC, ref logFont);
            this.OnImeStart(hIMC);
        }

        private void OnImeEndPrivate(IntPtr hIMC) {
            Win32.ImmReleaseContext(this.Handle, hIMC);
            this.OnImeEnd(hIMC);
        }

        private void OnImeResultStrPrivate(IntPtr hIMC, string strResult) {
            var CompositionForm = new Win32.COMPOSITIONFORM() {
                dwStyle = Win32.CFS_FORCE_POSITION,
                ptCurrentPos = m_core.Caret.Location
            };
            Win32.ImmSetCompositionWindow(hIMC, ref CompositionForm);
            this.OnImeResultStr(hIMC, strResult);
        }

        private void m_timer_Tick(object sender, EventArgs e) {
            if (m_core.Scroll.HoverScrollBar != STTextBoxScrollInfo.ScrollBarType.None) {
                return;
            }
            lock (m_obj_sync) {
                m_core.Scroll.CountDown--;
            }
            if (m_core.Scroll.CountDown 

Web Proxy Viewer  |  New URL  |  Original Page