/// <summary>
        /// Gets the selection start and length.
        /// </summary>
        /// <param name="start">Start of selection.</param>
        /// <param name="length">Length of selection.</param>
        public void GetSel(out int start, out int length)
        {
            int liEnd = 0;

            EnhTextBoxAPIFunctions.SendMessageLongRef(Handle, EnhTextBoxAPIFunctions.Messages.EM_GETSEL, out start, out liEnd);
            length = liEnd - start;
        }
        /// <summary>
        /// Locks the window so that no redrawing occurs.
        /// </summary>
        public void LockWindow()
        {
            if (miLockCount == 0)
            {
                mbSuspendPainting = true;
                EnhTextBoxAPIFunctions.SendMessageLong(Handle, EnhTextBoxAPIFunctions.Messages.WM_SETREDRAW, 0, 0);
            }
            ;

            miLockCount++;
        }
        /// <summary>
        /// Sets the scoll position of the text box.
        /// </summary>
        /// <remarks>This code compensates for the EM_GETSCROLLPOS message limitations.</remarks>
        /// <param name="value">The new scroll position.</param>
        protected void SetScrollPos(Point value)
        {
            // Save the original value
            EnhTextBoxAPIFunctions.POINTAPI lpOriginal = (EnhTextBoxAPIFunctions.POINTAPI)value;
            if (lpOriginal.Y < 0)
            {
                lpOriginal.Y = 0;
            }
            if (lpOriginal.X < 0)
            {
                lpOriginal.X = 0;
            }

            // Default factored value to original value with Y Factor compensation
            EnhTextBoxAPIFunctions.POINTAPI lpFactored = (EnhTextBoxAPIFunctions.POINTAPI)value;
            lpFactored.Y = (int)((double)lpOriginal.Y * mdScrollPosYfactor);

            // Current result
            EnhTextBoxAPIFunctions.POINTAPI lpResult = (EnhTextBoxAPIFunctions.POINTAPI)value;

            EnhTextBoxAPIFunctions.SendMessagePoint(this.Handle, EnhTextBoxAPIFunctions.Messages.EM_SETSCROLLPOS, 0, ref lpFactored);
            EnhTextBoxAPIFunctions.SendMessagePoint(this.Handle, EnhTextBoxAPIFunctions.Messages.EM_GETSCROLLPOS, 0, ref lpResult);

            int liLoopCount = 0;
            int liMaxLoop   = 100;

            while (lpResult.Y != lpOriginal.Y)
            {
                // Adjust the input.
                if (lpResult.Y > lpOriginal.Y)
                {
                    lpFactored.Y -= (lpResult.Y - lpOriginal.Y) / 2 - 1;
                }
                else
                if (lpResult.Y < lpOriginal.Y)
                {
                    lpFactored.Y += (lpOriginal.Y - lpResult.Y) / 2 + 1;
                }

                // test the new input.
                EnhTextBoxAPIFunctions.SendMessagePoint(this.Handle, EnhTextBoxAPIFunctions.Messages.EM_SETSCROLLPOS, 0, ref lpFactored);
                EnhTextBoxAPIFunctions.SendMessagePoint(this.Handle, EnhTextBoxAPIFunctions.Messages.EM_GETSCROLLPOS, 0, ref lpResult);

                // save new factor, test for exit.
                liLoopCount++;
                if (liLoopCount >= liMaxLoop || lpResult.Y == lpOriginal.Y)
                {
                    mdScrollPosYfactor = (double)lpFactored.Y / (double)lpOriginal.Y;
                    break;
                }
            }
        }
        /// <summary>
        /// Unlocks and invalidates the window to resume redrawing.
        /// </summary>
        public void UnlockWindow()
        {
            miLockCount--;

            if (miLockCount == 0)
            {
                mbSuspendPainting = false;
                EnhTextBoxAPIFunctions.SendMessageLong(Handle, EnhTextBoxAPIFunctions.Messages.WM_SETREDRAW, 1, 0);
                Invalidate();
            }

            if (miLockCount < 0)
            {
                miLockCount = 0;
            }
        }
        /// <summary>
        /// Returns true if the selection is in a forward direction (cursor is after selection)
        /// or false if the selection is in a backward direction (cursor is before selection).
        /// </summary>
        /// <returns>True if selection is forward.</returns>
        protected bool IsSelectionForward()
        {
            EnhTextBoxAPIFunctions.POINTAPI lpCaretPos;

            EnhTextBoxAPIFunctions.GetCaretPos(out lpCaretPos);
            lpCaretPos.X++;
            lpCaretPos.Y++;

            int liCaretChar = GetCharIndexFromPosition(new Point(lpCaretPos.X, lpCaretPos.Y));

            int liStart, liLength;

            GetSel(out liStart, out liLength);

            if (liLength > 0 && liCaretChar <= liStart)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
 /// <summary>
 /// Sets the selection start and length.
 /// </summary>
 /// <param name="start">The start of the selection.</param>
 /// <param name="length">The length of the selection.</param>
 public void SetSel(int start, int length)
 {
     EnhTextBoxAPIFunctions.SendMessageLong(Handle, EnhTextBoxAPIFunctions.Messages.EM_SETSEL, start, start + length);
 }
 /// <summary>
 /// Gets the scroll position of the text box.
 /// </summary>
 /// <returns>The point denoting the scroll position.</returns>
 protected Point GetScrollPos()
 {
     EnhTextBoxAPIFunctions.POINTAPI lpScrollPoint = new EnhTextBoxAPIFunctions.POINTAPI();
     EnhTextBoxAPIFunctions.SendMessagePoint(this.Handle, EnhTextBoxAPIFunctions.Messages.EM_GETSCROLLPOS, 0, ref lpScrollPoint);
     return(new Point(lpScrollPoint.X, lpScrollPoint.Y));
 }