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

using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace _SCREEN_CAPTURE
{
    /// <summary>
    /// 
    /// </summary>
    internal partial class ImageProcessBox : Control
    {
        /// <summary>
        /// 
        /// </summary>
        public ImageProcessBox() {
            InitializeComponent();
            InitMember();

            this.ForeColor = Color.White;
            this.BackColor = Color.Black;
            this.Dock = DockStyle.Fill;

            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        }

        private void InitMember() {
            this.dotColor = Color.Yellow;
            this.lineColor = Color.Cyan;
            this.magnifySize = new Size(15, 15);
            this.magnifyTimes = 7;
            this.isDrawOperationDot = true;
            this.isSetClip = true;
            this.isShowInfo = true;
            this.autoSizeFromImage = true;
            this.canReset = true;
            m_pen = new Pen(lineColor, 1);
            m_sb = new SolidBrush(dotColor);
            this.selectedRectangle = new Rectangle();
            this.ClearDraw();
            m_rectDots = new Rectangle[8];
            for (int i = 0; i < 8; i++) {
                m_rectDots[i] = new Rectangle(-10, -10, 5, 5);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        //貌似析构函数不执行
        ~ImageProcessBox() {
            m_pen.Dispose();
            m_sb.Dispose();
            m_bmpDark.Dispose();
            this.baseImage.Dispose();
        }
        /// <summary>
        /// 
        /// </summary>
        public void DeleResource() {
            m_pen.Dispose();
            m_sb.Dispose();
            if (this.baseImage != null) {
                m_bmpDark.Dispose();
                this.baseImage.Dispose();
            }
        }

        #region Properties

        private Image baseImage;
        /// <summary>
        /// 获取或设置用于被操作的图像
        /// </summary>
        [Category("Custom"), Description("获取或设置用于被操作的图像")]
        public Image BaseImage {
            get { return baseImage; }
            set {
                baseImage = value;
                this.BuildBitmap();
            }
        }

        private Color dotColor;
        /// <summary>
        /// 获取或设置操作框点的颜色
        /// </summary>
        [Description("获取或设置操作框点的颜色")]
        [DefaultValue(typeof(Color), "Yellow"), Category("Custom")]
        public Color DotColor {
            get { return dotColor; }
            set { dotColor = value; }
        }

        private Color lineColor;
        /// <summary>
        /// 获取或设置操作框线条的颜色
        /// </summary>
        [Description("获取或设置操作框线条的颜色")]
        [DefaultValue(typeof(Color), "Cyan"), Category("Custom")]
        public Color LineColor {
            get { return lineColor; }
            set { lineColor = value; }
        }

        private Rectangle selectedRectangle;
        /// <summary>
        /// 获取当前选中的区域
        /// </summary>
        [Browsable(false)]
        public Rectangle SelectedRectangle {
            get {
                Rectangle rectTemp = selectedRectangle;
                rectTemp.Width++; rectTemp.Height++;
                return rectTemp;
            }
        }

        private Size magnifySize;
        /// <summary>
        /// 获取或设置放大图像的原图大小尺寸
        /// </summary>
        [Description("获取或设置放大图像的原图大小尺寸")]
        [DefaultValue(typeof(Size), "15,15"), Category("Custom")]
        public Size MagnifySize {
            get { return magnifySize; }
            set {
                magnifySize = value;
                if (magnifySize.Width < 5) magnifySize.Width = 5;
                if (magnifySize.Width > 20) magnifySize.Width = 20;
                if (magnifySize.Height < 5) magnifySize.Height = 5;
                if (magnifySize.Height > 20) magnifySize.Height = 20;
            }
        }

        private int magnifyTimes;
        /// <summary>
        /// 获取或设置图像放大的倍数
        /// </summary>
        [Description("获取或设置图像放大的倍数")]
        [DefaultValue(7), Category("Custom")]
        public int MagnifyTimes {
            get { return magnifyTimes; }
            set {
                magnifyTimes = value;
                if (magnifyTimes < 3) magnifyTimes = 3;
                if (magnifyTimes > 10) magnifyTimes = 10;
            }
        }

        private bool isDrawOperationDot;
        /// <summary>
        /// 获取或设置是否绘制操作框点
        /// </summary>
        [Description("获取或设置是否绘制操作框点")]
        [DefaultValue(true), Category("Custom")]
        public bool IsDrawOperationDot {
            get { return isDrawOperationDot; }
            set {
                if (value == isDrawOperationDot) return;
                isDrawOperationDot = value;
                this.Invalidate();
            }
        }

        private bool isSetClip;
        /// <summary>
        /// 获取或设置是否限制鼠标操作区域
        /// </summary>
        [Description("获取或设置是否限制鼠标操作区域")]
        [DefaultValue(true), Category("Custom")]
        public bool IsSetClip {
            get { return isSetClip; }
            set { isSetClip = value; }
        }

        private bool isShowInfo;
        /// <summary>
        /// 获取或设置是否绘制信息展示
        /// </summary>
        [Description("获取或设置是否绘制信息展示")]
        [DefaultValue(true), Category("Custom")]
        public bool IsShowInfo {
            get { return isShowInfo; }
            set { isShowInfo = value; }
        }

        private bool autoSizeFromImage;
        /// <summary>
        /// 获取或设置是否根据图像大小自动调整控件尺寸
        /// </summary>
        [Description("获取或设置是否根据图像大小自动调整控件尺寸")]
        [DefaultValue(true), Category("Custom")]
        public bool AutoSizeFromImage {
            get { return autoSizeFromImage; }
            set {
                if (value && this.baseImage != null) {
                    this.Width = this.baseImage.Width;
                    this.Height = this.baseImage.Height;
                }
                autoSizeFromImage = value;
            }
        }

        private bool isDrawed;
        /// <summary>
        /// 获取当前是否绘制的有区域
        /// </summary>
        [Browsable(false)]
        public bool IsDrawed {
            get { return isDrawed; }
        }

        private bool isStartDraw;
        /// <summary>
        /// 获取当前是否开始绘制
        /// </summary>
        [Browsable(false)]
        public bool IsStartDraw {
            get { return isStartDraw; }
        }

        private bool isMoving;
        /// <summary>
        /// 获取当前操作框是否正在移动
        /// </summary>
        [Browsable(false)]
        public bool IsMoving {
            get { return isMoving; }
        }

        private bool canReset;
        /// <summary>
        /// 获取或设置操作框是否锁定
        /// </summary>
        [Browsable(false)]
        public bool CanReset {
            get { return canReset; }
            set {
                canReset = value;
                if (!canReset) this.Cursor = Cursors.Default;
            }
        }
        #endregion

        #region Member variable

        private bool m_bMouseEnter;
        private bool m_bLockH;
        private bool m_bLockW;
        private Point m_ptOriginal;
        private Point m_ptCurrent;
        private Point m_ptTempStarPos;
        private Rectangle[] m_rectDots;
        private Rectangle m_rectClip;

        private Bitmap m_bmpDark;
        private Pen m_pen;
        private SolidBrush m_sb;

        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {        //根据情况是否开始绘制操作框
                if (!this.IsDrawed || this.Cursor != Cursors.Default) {
                    m_rectClip = this.DisplayRectangle;
                    if (this.baseImage != null) {
                        if (this.isSetClip) {
                            if (e.X > this.baseImage.Width || e.Y > this.baseImage.Height) return;
                            m_rectClip.Intersect(new Rectangle(0, 0, this.baseImage.Width, this.baseImage.Height));
                        }
                    }
                    Cursor.Clip = RectangleToScreen(m_rectClip);
                    isStartDraw = true;
                    m_ptOriginal = e.Location;
                }
            }
            this.Focus();
            base.OnMouseDown(e);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseMove(MouseEventArgs e) {
            m_ptCurrent = e.Location;
            m_bMouseEnter = true;

            #region Process OperationBox

            if (isDrawed && this.canReset) {        //如果已经绘制 并且可以操作选取 判断操作类型
                this.SetCursorStyle(e.Location);
                if (isStartDraw && this.isDrawOperationDot) {
                    if (m_rectDots[0].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal.X = this.selectedRectangle.Right;
                        m_ptOriginal.Y = this.selectedRectangle.Bottom;
                    } else if (m_rectDots[1].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal.Y = this.selectedRectangle.Bottom;
                        m_bLockW = true;
                    } else if (m_rectDots[2].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal.X = this.selectedRectangle.X;
                        m_ptOriginal.Y = this.selectedRectangle.Bottom;
                    } else if (m_rectDots[3].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal.X = this.selectedRectangle.Right;
                        m_bLockH = true;
                    } else if (m_rectDots[4].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal.X = this.selectedRectangle.X;
                        m_bLockH = true;
                    } else if (m_rectDots[5].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal.X = this.selectedRectangle.Right;
                        m_ptOriginal.Y = this.selectedRectangle.Y;
                    } else if (m_rectDots[6].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal.Y = this.selectedRectangle.Y;
                        m_bLockW = true;
                    } else if (m_rectDots[7].Contains(e.Location)) {
                        isDrawed = false;
                        m_ptOriginal = this.selectedRectangle.Location;
                    } else if (this.selectedRectangle.Contains(e.Location)) {
                        isDrawed = false;
                        isMoving = true;
                    }
                }
                base.OnMouseMove(e);
                return;
            }

            #endregion

            #region Calculate the operationbox

            if (isStartDraw) {
                if (isMoving) {     //如果移动选区 只重置 location
                    Point ptLast = this.selectedRectangle.Location;
                    this.selectedRectangle.X = m_ptTempStarPos.X + e.X - m_ptOriginal.X;
                    this.selectedRectangle.Y = m_ptTempStarPos.Y + e.Y - m_ptOriginal.Y;
                    if (this.selectedRectangle.X < 0) this.selectedRectangle.X = 0;
                    if (this.selectedRectangle.Y < 0) this.selectedRectangle.Y = 0;
                    if (this.selectedRectangle.Right > m_rectClip.Width) this.selectedRectangle.X = m_rectClip.Width - this.selectedRectangle.Width - 1;
                    if (this.selectedRectangle.Bottom > m_rectClip.Height) this.selectedRectangle.Y = m_rectClip.Height - this.selectedRectangle.Height - 1;
                    if (this.Location == ptLast) return;
                } else {            //其他情况 判断是锁定高 还是锁定宽
                    if (Math.Abs(e.X - m_ptOriginal.X) > 1 || Math.Abs(e.Y - m_ptOriginal.Y) > 1) {
                        if (!m_bLockW) {
                            selectedRectangle.X = m_ptOriginal.X - e.X < 0 ? m_ptOriginal.X : e.X;
                            selectedRectangle.Width = Math.Abs(m_ptOriginal.X - e.X);
                        }
                        if (!m_bLockH) {
                            selectedRectangle.Y = m_ptOriginal.Y - e.Y < 0 ? m_ptOriginal.Y : e.Y;
                            selectedRectangle.Height = Math.Abs(m_ptOriginal.Y - e.Y);
                        }
                    }
                }
                this.Invalidate();
            }

            #endregion

            if (this.baseImage != null && !isDrawed && !isMoving && isShowInfo)
                this.Invalidate();
            base.OnMouseMove(e);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseLeave(EventArgs e) {
            m_bMouseEnter = false;
            this.Invalidate();
            base.OnMouseLeave(e);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {        //如果绘制太小 则视为无效
                if (this.selectedRectangle.Width >= 4 && this.selectedRectangle.Height >= 4)
                    isDrawed = true;
                else
                    this.ClearDraw();
                isMoving = m_bLockH = m_bLockW = false; //取消锁定
                isStartDraw = false;
                m_ptTempStarPos = this.selectedRectangle.Location;
                Cursor.Clip = new Rectangle();
            } else if (e.Button == MouseButtons.Right)
                this.ClearDraw();
            this.Invalidate();
            base.OnMouseUp(e);
        }
        /// <summary>
        /// 响应四个按键实现精确移动
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyPress(KeyPressEventArgs e) {
            if (e.KeyChar == 'w')
                Win32.SetCursorPos(MousePosition.X, MousePosition.Y - 1);
            else if (e.KeyChar == 's')
                Win32.SetCursorPos(MousePosition.X, MousePosition.Y + 1);
            else if (e.KeyChar == 'a')
                Win32.SetCursorPos(MousePosition.X - 1, MousePosition.Y);
            else if (e.KeyChar == 'd')
                Win32.SetCursorPos(MousePosition.X + 1, MousePosition.Y);
            base.OnKeyPress(e);
        }
/// <summary>
/// 
/// </summary>
/// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e) {
            Graphics g = e.Graphics;
            if (this.baseImage != null) {
                g.DrawImage(m_bmpDark, 0, 0);
                g.DrawImage(this.baseImage, this.selectedRectangle, this.selectedRectangle, GraphicsUnit.Pixel);
            }
            this.DrawOperationBox(g);
            if (this.baseImage != null && !isDrawed && !isMoving && m_bMouseEnter && isShowInfo)
                DrawInfo(e.Graphics);
            base.OnPaint(e);
        }
        /// <summary>
        /// 绘制操作框
        /// </summary>
        /// <param name="g"></param>
        protected virtual void DrawOperationBox(Graphics g) {

            #region Draw SizeInfo

            string strDrawSize = "X:" + this.selectedRectangle.X + " Y:" + this.selectedRectangle.Y +
                " W:" + (this.selectedRectangle.Width + 1) + " H:" + (this.selectedRectangle.Height + 1);
            Size seStr = TextRenderer.MeasureText(strDrawSize, this.Font);
            int tempX = this.selectedRectangle.X;
            int tempY = this.selectedRectangle.Y - seStr.Height - 5;
            if (!m_rectClip.IsEmpty)
                if (tempX + seStr.Width >= m_rectClip.Right) tempX -= seStr.Width;
            if (tempY <= 0) tempY += seStr.Height + 10;

            m_sb.Color = Color.FromArgb(125, 0, 0, 0);
            g.FillRectangle(m_sb, tempX, tempY, seStr.Width, seStr.Height);
            m_sb.Color = this.ForeColor;
            g.DrawString(strDrawSize, this.Font, m_sb, tempX, tempY);

            #endregion

            if (!this.isDrawOperationDot) {
                m_pen.Width = 3; m_pen.Color = this.lineColor;
                g.DrawRectangle(m_pen, this.selectedRectangle);
                return;
            }
            //计算八个顶点位置
            m_rectDots[0].Y = m_rectDots[1].Y = m_rectDots[2].Y = this.selectedRectangle.Y - 2;
            m_rectDots[5].Y = m_rectDots[6].Y = m_rectDots[7].Y = this.selectedRectangle.Bottom - 2;
            m_rectDots[0].X = m_rectDots[3].X = m_rectDots[5].X = this.selectedRectangle.X - 2;
            m_rectDots[2].X = m_rectDots[4].X = m_rectDots[7].X = this.selectedRectangle.Right - 2;
            m_rectDots[3].Y = m_rectDots[4].Y = this.selectedRectangle.Y + this.selectedRectangle.Height / 2 - 2;
            m_rectDots[1].X = m_rectDots[6].X = this.selectedRectangle.X + this.selectedRectangle.Width / 2 - 2;
            m_pen.Width = 1; m_pen.Color = this.lineColor;
            g.DrawRectangle(m_pen, this.selectedRectangle);
            m_sb.Color = this.dotColor;
            foreach (Rectangle rect in m_rectDots) {
                g.FillRectangle(m_sb, rect);
            }
            if (this.selectedRectangle.Width <= 10 || this.selectedRectangle.Height <= 10)
                g.DrawRectangle(m_pen, this.selectedRectangle);
        }
        /// <summary>
        /// 绘制图像放大信息
        /// </summary>
        /// <param name="g"></param>
        protected virtual void DrawInfo(Graphics g) {

            #region Calculate point

            int tempX = m_ptCurrent.X + 20;
            int tempY = m_ptCurrent.Y + 20;
            int tempW = this.magnifySize.Width * this.magnifyTimes + 8;
            int tempH = this.magnifySize.Width * this.magnifyTimes + 12 + this.Font.Height * 3;
            if (!m_rectClip.IsEmpty) {
                if (tempX + tempW >= this.m_rectClip.Right) tempX -= tempW + 30;
                if (tempY + tempH >= this.m_rectClip.Bottom) tempY -= tempH + 30;
            } else {
                if (tempX + tempW >= this.ClientRectangle.Width) tempX -= tempW + 30;
                if (tempY + tempH >= this.ClientRectangle.Height) tempY -= tempH + 30;
            }
            Rectangle tempRectBorder = new Rectangle(tempX + 2, tempY + 2, tempW - 4, this.magnifySize.Width * this.magnifyTimes + 4);

            #endregion

            m_sb.Color = Color.FromArgb(200, 0, 0, 0);
            g.FillRectangle(m_sb, tempX, tempY, tempW, tempH);
            m_pen.Width = 2; m_pen.Color = Color.White;
            g.DrawRectangle(m_pen, tempRectBorder);

            #region Draw the magnified image

            using (Bitmap bmpSrc = new Bitmap(this.magnifySize.Width, this.magnifySize.Height, PixelFormat.Format32bppArgb)) {
                using (Graphics gp = Graphics.FromImage(bmpSrc)) {
                    gp.SetClip(new Rectangle(0, 0, this.magnifySize.Width, this.magnifySize.Height));
                    gp.DrawImage(this.baseImage, -(m_ptCurrent.X - this.magnifySize.Width / 2), -(m_ptCurrent.Y - this.magnifySize.Height / 2));
                }
                using (Bitmap bmpInfo = this.MagnifyImage(bmpSrc, this.magnifyTimes)) {
                    g.DrawImage(bmpInfo, tempX + 4, tempY + 4);
                }
            }

            #endregion

            m_pen.Width = this.magnifyTimes - 2;
            m_pen.Color = Color.FromArgb(125, 0, 255, 255);
            int tempCenterX = tempX + (tempW + (this.magnifySize.Width % 2 == 0 ? this.magnifyTimes : 0)) / 2;
            int tempCenterY = tempY + 2 + (tempRectBorder.Height + (this.MagnifySize.Height % 2 == 0 ? this.magnifyTimes : 0)) / 2;
            g.DrawLine(m_pen, tempCenterX, tempY + 4, tempCenterX, tempRectBorder.Bottom - 2);
            g.DrawLine(m_pen, tempX + 4, tempCenterY, tempX + tempW - 4, tempCenterY);

            #region Draw Info

            m_sb.Color = this.ForeColor;
            if(m_ptCurrent.X<0 || m_ptCurrent.Y < 0) { return; }
            Color clr = ((Bitmap)this.baseImage).GetPixel(m_ptCurrent.X, m_ptCurrent.Y);
            g.DrawString("大小: " + (this.selectedRectangle.Width + 1) + " x "
                + (this.selectedRectangle.Height + 1),
                this.Font, m_sb, tempX + 2, tempRectBorder.Bottom + 2);
            g.DrawString(clr.A + "," + clr.R + "," + clr.G + "," + clr.B,
                this.Font, m_sb, tempX + 2, tempRectBorder.Bottom + 2 + this.Font.Height);
            g.DrawString("0x" + clr.A.ToString("X").PadLeft(2, '0') +
                clr.R.ToString("X").PadLeft(2, '0') +
                clr.G.ToString("X").PadLeft(2, '0') +
                clr.B.ToString("X").PadLeft(2, '0'),
                this.Font, m_sb, tempX + 2, tempRectBorder.Bottom + 2 + this.Font.Height * 2);
            m_sb.Color = clr;
            g.FillRectangle(m_sb, tempX + tempW - 2 - this.Font.Height,
                tempY + tempH - 2 - this.Font.Height,
                this.Font.Height,
                this.Font.Height);
            g.DrawRectangle(Pens.Cyan, tempX + tempW - 2 - this.Font.Height,
                tempY + tempH - 2 - this.Font.Height,
                this.Font.Height,
                this.Font.Height);
            g.FillRectangle(m_sb, tempCenterX - this.magnifyTimes / 2,
                tempCenterY - this.magnifyTimes / 2,
                this.magnifyTimes,
                this.magnifyTimes);
            g.DrawRectangle(Pens.Cyan, tempCenterX - this.magnifyTimes / 2,
                tempCenterY - this.magnifyTimes / 2,
                this.magnifyTimes - 1,
                this.magnifyTimes - 1);

            #endregion
        }
        //放大图形
        private Bitmap MagnifyImage(Bitmap bmpSrc, int times) {
            Bitmap bmpNew = new Bitmap(bmpSrc.Width * times, bmpSrc.Height * times, PixelFormat.Format32bppArgb);
            BitmapData bmpSrcData = bmpSrc.LockBits(new Rectangle(0, 0, bmpSrc.Width, bmpSrc.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData bmpNewData = bmpNew.LockBits(new Rectangle(0, 0, bmpNew.Width, bmpNew.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            byte[] bySrcData = new byte[bmpSrcData.Height * bmpSrcData.Stride];
            Marshal.Copy(bmpSrcData.Scan0, bySrcData, 0, bySrcData.Length);
            byte[] byNewData = new byte[bmpNewData.Height * bmpNewData.Stride];
            Marshal.Copy(bmpNewData.Scan0, byNewData, 0, byNewData.Length);
            for (int y = 0, lenY = bmpSrc.Height; y < lenY; y++) {
                for (int x = 0, lenX = bmpSrc.Width; x < lenX; x++) {
                    for (int cy = 0; cy < times; cy++) {
                        for (int cx = 0; cx < times; cx++) {
                            byNewData[(x * times + cx) * 4 + ((y * times + cy) * bmpNewData.Stride)] = bySrcData[x * 4 + y * bmpSrcData.Stride];
                            byNewData[(x * times + cx) * 4 + ((y * times + cy) * bmpNewData.Stride) + 1] = bySrcData[x * 4 + y * bmpSrcData.Stride + 1];
                            byNewData[(x * times + cx) * 4 + ((y * times + cy) * bmpNewData.Stride) + 2] = bySrcData[x * 4 + y * bmpSrcData.Stride + 2];
                            byNewData[(x * times + cx) * 4 + ((y * times + cy) * bmpNewData.Stride) + 3] = bySrcData[x * 4 + y * bmpSrcData.Stride + 3];
                        }
                    }
                }
            }
            Marshal.Copy(byNewData, 0, bmpNewData.Scan0, byNewData.Length);
            bmpSrc.UnlockBits(bmpSrcData);
            bmpNew.UnlockBits(bmpNewData);
            return bmpNew;
        }
        //设置鼠标指针样式
        private void SetCursorStyle(Point loc) {
            if (m_rectDots[0].Contains(loc) || m_rectDots[7].Contains(loc))
                this.Cursor = Cursors.SizeNWSE;
            else if (m_rectDots[1].Contains(loc) || m_rectDots[6].Contains(loc))
                this.Cursor = Cursors.SizeNS;
            else if (m_rectDots[2].Contains(loc) || m_rectDots[5].Contains(loc))
                this.Cursor = Cursors.SizeNESW;
            else if (m_rectDots[3].Contains(loc) || m_rectDots[4].Contains(loc))
                this.Cursor = Cursors.SizeWE;
            else if (this.selectedRectangle.Contains(loc) /*&& this.canReset*/)
                this.Cursor = Cursors.SizeAll;
            else
                this.Cursor = Cursors.Default;
        }

        private void BuildBitmap() {
            if (this.baseImage == null) return;
            m_bmpDark = new Bitmap(this.baseImage);
            using (Graphics g = Graphics.FromImage(m_bmpDark)) {
                SolidBrush sb = new SolidBrush(Color.FromArgb(125, 0, 0, 0));
                g.FillRectangle(sb, 0, 0, m_bmpDark.Width, m_bmpDark.Height);
                sb.Dispose();
            }
        }
        /// <summary>
        /// 清空所有操作
        /// </summary>
        public void ClearDraw() {
            isDrawed = false;
            this.selectedRectangle.X = this.selectedRectangle.Y = -100;
            this.selectedRectangle.Width = this.selectedRectangle.Height = 0;
            this.Cursor = Cursors.Default;
            this.Invalidate();
        }
        /// <summary>
        /// 手动设置一个块选中区域
        /// </summary>
        /// <param name="rect">要选中区域</param>
        public void SetSelectRect(Rectangle rect) {
            rect.Intersect(this.DisplayRectangle);
            if (rect.IsEmpty) return;
            rect.Width--; rect.Height--;
            if (this.selectedRectangle == rect) return;
            this.selectedRectangle = rect;
            this.Invalidate();
        }
        /// <summary>
        /// 手动设置一个块选中区域
        /// </summary>
        /// <param name="pt">要选中区域的坐标</param>
        /// <param name="se">要选中区域的大小</param>
        public void SetSelectRect(Point pt, Size se) {
            Rectangle rectTemp = new Rectangle(pt, se);
            rectTemp.Intersect(this.DisplayRectangle);
            if (rectTemp.IsEmpty) return;
            rectTemp.Width--; rectTemp.Height--;
            if (this.selectedRectangle == rectTemp) return;
            this.selectedRectangle = rectTemp;
            this.Invalidate();
        }
        /// <summary>
        /// 手动设置一个块选中区域
        /// </summary>
        /// <param name="x">要选中区域的x坐标</param>
        /// <param name="y">要选中区域的y坐标</param>
        /// <param name="w">要选中区域的宽度</param>
        /// <param name="h">要选中区域的高度</param>
        public void SetSelectRect(int x, int y, int w, int h) {
            Rectangle rectTemp = new Rectangle(x, y, w, h);
            rectTemp.Intersect(this.DisplayRectangle);
            if (rectTemp.IsEmpty) return;
            rectTemp.Width--; rectTemp.Height--;
            if (this.selectedRectangle == rectTemp) return;
            this.selectedRectangle = rectTemp;
            this.Invalidate();
        }
        /// <summary>
        /// 手动设置信息显示的位置
        /// </summary>
        /// <param name="pt">要显示的位置</param>
        public void SetInfoPoint(Point pt) {
            if (m_ptCurrent == pt) return;
            m_ptCurrent = pt;
            m_bMouseEnter = true;
            this.Invalidate();
        }
        /// <summary>
        /// 手动设置信息显示的位置
        /// </summary>
        /// <param name="x">要显示位置的x坐标</param>
        /// <param name="y">要显示位置的y坐标</param>
        public void SetInfoPoint(int x, int y) {
            if (m_ptCurrent.X == x && m_ptCurrent.Y == y) return;
            m_ptCurrent.X = x;
            m_ptCurrent.Y = y;
            m_bMouseEnter = true;
            this.Invalidate();
        }
        /// <summary>
        /// 获取操作框内的图像
        /// </summary>
        /// <returns>结果图像</returns>
        public Bitmap GetResultBmp() {
            if (this.baseImage == null) return null;
            Bitmap bmp = new Bitmap(this.selectedRectangle.Width + 1, this.selectedRectangle.Height + 1);
            using (Graphics g = Graphics.FromImage(bmp)) {
                g.DrawImage(this.baseImage, -this.selectedRectangle.X, -this.selectedRectangle.Y);
            }
            //Bitmap bmp = ((Bitmap)this.baseImage).Clone(this.selectedRectangle, this.baseImage.PixelFormat);
            return bmp;
        }
    }
}
