using System; using System.Drawing; using System.Runtime.InteropServices; namespace Server.Helper.HexEditor; public class Caret { private int _startIndex; private int _endIndex; private bool _isCaretActive; private bool _isCaretHidden; private Point _location; private HexEditor _editor; public int SelectionStart { get { if (_endIndex < _startIndex) { return _endIndex; } return _startIndex; } } public int SelectionLength { get { if (_endIndex < _startIndex) { return _startIndex - _endIndex; } return _endIndex - _startIndex; } } public bool Focused => _isCaretActive; public int CurrentIndex => _endIndex; public Point Location => _location; public event EventHandler SelectionStartChanged; public event EventHandler SelectionLengthChanged; public Caret(HexEditor editor) { _editor = editor; _isCaretActive = false; _startIndex = 0; _endIndex = 0; _isCaretHidden = true; _location = new Point(0, 0); } private bool Create(IntPtr hWHandler) { if (!_isCaretActive) { _isCaretActive = true; return CreateCaret(hWHandler, IntPtr.Zero, 0, (int)_editor.CharSize.Height - 2); } return false; } private bool Show(IntPtr hWnd) { if (_isCaretActive) { _isCaretHidden = false; return ShowCaret(hWnd); } return false; } public bool Hide(IntPtr hWnd) { if (_isCaretActive && !_isCaretHidden) { _isCaretHidden = true; return HideCaret(hWnd); } return false; } public bool Destroy() { if (_isCaretActive) { _isCaretActive = false; DeSelect(); DestroyCaret(); } return false; } public void SetStartIndex(int index) { _startIndex = index; _endIndex = _startIndex; if (this.SelectionStartChanged != null) { this.SelectionStartChanged(this, EventArgs.Empty); } if (this.SelectionLengthChanged != null) { this.SelectionLengthChanged(this, EventArgs.Empty); } } public void SetEndIndex(int index) { _endIndex = index; if (this.SelectionStartChanged != null) { this.SelectionStartChanged(this, EventArgs.Empty); } if (this.SelectionLengthChanged != null) { this.SelectionLengthChanged(this, EventArgs.Empty); } } public void SetCaretLocation(Point start) { Create(_editor.Handle); _location = start; SetCaretPos(_location.X, _location.Y); Show(_editor.Handle); } public bool IsSelected(int byteIndex) { if (SelectionStart <= byteIndex) { return byteIndex < SelectionStart + SelectionLength; } return false; } private void DeSelect() { if (_endIndex < _startIndex) { _startIndex = _endIndex; } else { _endIndex = _startIndex; } if (this.SelectionStartChanged != null) { this.SelectionStartChanged(this, EventArgs.Empty); } if (this.SelectionLengthChanged != null) { this.SelectionLengthChanged(this, EventArgs.Empty); } } [DllImport("user32.dll", SetLastError = true)] private static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight); [DllImport("user32.dll", SetLastError = true)] private static extern bool DestroyCaret(); [DllImport("user32.dll", SetLastError = true)] private static extern bool SetCaretPos(int x, int y); [DllImport("user32.dll", SetLastError = true)] private static extern bool ShowCaret(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true)] private static extern bool HideCaret(IntPtr hWnd); }