C# HexEdit

新建HexEditProperties.cs,将以下代码拷贝至该文件

using System.Drawing;

namespace TestHexEdit
{
    public class HexEditProperties
    {
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public HexEditProperties()
        {
            //默认显示头部
            IsSupportDisplayHexHead = true;
            HexHeadHeight = 25;
            HexHeadBackgroundTopColor = Color.FromArgb(236, 244, 252);
            HexHeadBackgroundBottomColor = Color.FromArgb(220, 230, 245);
            HexHeadBackgroundBottomFLineColor = Color.FromArgb(228, 239, 251);
            HexHeadBackgroundBottomSLineColor = Color.FromArgb(205, 218, 234);
            HexHeadBackgroundBottomTLineColor = Color.FromArgb(160, 175, 195);
            HexHeadFontColor = Color.Black;
            HexHeadStaffColor = Color.Black;

            //设置背景色
            HexBackgroundColor = Color.White;

            //设置背景字体
            HexBackgroundFont = new Font("宋体", 10);

            //设置字体显示类型
            HexDataType = EncodingType.ANSI;
            HexDataFontColor = Color.Black;

            //设置外部线条
            HexOutLineWidth = 2;
            HexOutLineColor = Color.Black;

            //默认显示地址栏
            IsSupportHexAddress = true;
            HexAddressWidth = 100;
            HexAddressShowBit = AddressBit.Bit8;
            HexAddressBackgroundColor = Color.White;
            HexAddressFontColor = Color.Black;

            //设置选择框的颜色
            HexSelectBorderFColor = Color.FromArgb(213, 231, 252);
            HexSelectBorderSColor = Color.FromArgb(193, 220, 252);
            HexSelectBorderOLColor = Color.FromArgb(235, 244, 253);

            //设置菜单属性
            IsSupportDisplayMenu = true;
        }

        #region 控件头部属性

        /// <summary>
        /// 用于判定是否显示HexEdit的头部
        /// </summary>
        private bool _IsSupportDisplayHexHead;
        public bool IsSupportDisplayHexHead
        {
            get
            {
                return _IsSupportDisplayHexHead;
            }
            set
            {
                _IsSupportDisplayHexHead = value;
            }
        }

        /// <summary>
        /// HexEdit的Head的高度
        /// </summary>
        private int _HexHeadHeight;
        public int HexHeadHeight
        {
            get
            {
                return _HexHeadHeight;
            }
            set
            {
                _HexHeadHeight = value;
            }
        }

        /// <summary>
        /// HexEdit的Background的上半部分颜色
        /// </summary>
        private Color _HexHeadBackgroundTopColor;
        public Color HexHeadBackgroundTopColor
        {
            get
            {
                return _HexHeadBackgroundTopColor;
            }
            set
            {
                _HexHeadBackgroundTopColor = value;
            }
        }

        /// <summary>
        /// HexEdit的Background的下半部分颜色
        /// </summary>
        private Color _HexHeadBackgroundBottomColor;
        public Color HexHeadBackgroundBottomColor
        {
            get
            {
                return _HexHeadBackgroundBottomColor;
            }
            set
            {
                _HexHeadBackgroundBottomColor = value;
            }
        }

        /// <summary>
        /// HexEdit的Background的下半部分第一个Line的颜色
        /// </summary>
        private Color _HexHeadBackgroundBottomFLineColor;
        public Color HexHeadBackgroundBottomFLineColor
        {
            get
            {
                return _HexHeadBackgroundBottomFLineColor;
            }
            set
            {
                _HexHeadBackgroundBottomFLineColor = value;
            }
        }

        /// <summary>
        /// HexEdit的Background的下半部分第二个Line的颜色
        /// </summary>
        private Color _HexHeadBackgroundBottomSLineColor;
        public Color HexHeadBackgroundBottomSLineColor
        {
            get
            {
                return _HexHeadBackgroundBottomSLineColor;
            }
            set
            {
                _HexHeadBackgroundBottomSLineColor = value;
            }
        }

        /// <summary>
        /// HexEdit的Background的下半部分第三个Line的颜色
        /// </summary>
        private Color _HexHeadBackgroundBottomTLineColor;
        public Color HexHeadBackgroundBottomTLineColor
        {
            get
            {
                return _HexHeadBackgroundBottomTLineColor;
            }
            set
            {
                _HexHeadBackgroundBottomTLineColor = value;
            }
        }

        /// <summary>
        /// HexEdit的标尺字体的颜色
        /// </summary>
        private Color _HexHeadFontColor;
        public Color HexHeadFontColor
        {
            get
            {
                return _HexHeadFontColor;
            }
            set
            {
                _HexHeadFontColor = value;
            }
        }

        /// <summary>
        /// HexEdit的标尺的颜色
        /// </summary>
        private Color _HexHeadStaffColor;
        public Color HexHeadStaffColor
        {
            get
            {
                return _HexHeadStaffColor;
            }
            set
            {
                _HexHeadStaffColor = value;
            }
        }

        #endregion

        #region 控件外部线条属性

        /// <summary>
        /// HexEdit的外部线条的颜色
        /// </summary>
        private Color _HexOutLineColor;
        public Color HexOutLineColor
        {
            get
            {
                return _HexOutLineColor;
            }
            set
            {
                _HexOutLineColor = value;
            }
        }

        /// <summary>
        /// HexEdit的外部线条的宽度
        /// </summary>
        private int _HexOutLineWidth;
        public int HexOutLineWidth
        {
            get
            {
                return _HexOutLineWidth;
            }
            set
            {
                _HexOutLineWidth = value;
            }
        }
        #endregion

        #region 背景色

        /// <summary>
        /// HexEdit的背景色的颜色
        /// </summary>
        private Color _HexBackgroundColor;
        public Color HexBackgroundColor
        {
            get
            {
                return _HexBackgroundColor;
            }
            set
            {
                _HexBackgroundColor = value;
            }
        }

        #endregion

        #region 控件字体属性
        private Font _HexBackgroundFont;
        public Font HexBackgroundFont
        {
            get
            {
                return _HexBackgroundFont;
            }
            set
            {
                _HexBackgroundFont = value;
            }
        }
        #endregion

        #region 控件数据属性
        /// <summary>
        /// 显示格式
        /// </summary>
        private EncodingType _HexDataType;
        public EncodingType HexDataType
        {
            get
            {
                return _HexDataType;
            }
            set
            {
                _HexDataType = value;
            }
        }
        public enum EncodingType
        {
            ANSI = 1,
            Unicond
        }

        /// <summary>
        /// 数据字体颜色
        /// </summary>
        private Color _HexDataFontColor;
        public Color HexDataFontColor
        {
            get
            {
                return _HexDataFontColor;
            }
            set
            {
                _HexDataFontColor = value;
            }
        }

        #endregion

        #region 控件地址栏属性
        /// <summary>
        /// 显示控件地址栏属性
        /// </summary>
        private bool _IsSupportHexAddress;
        public bool IsSupportHexAddress
        {
            get
            {
                return _IsSupportHexAddress;
            }
            set
            {
                _IsSupportHexAddress = value;
            }
        }

        /// <summary>
        /// 显示控件地址栏的背景颜色
        /// </summary>
        private Color _HexAddressBackgroundColor;
        public Color HexAddressBackgroundColor
        {
            get
            {
                return _HexAddressBackgroundColor;
            }
            set
            {
                _HexAddressBackgroundColor = value;
            }
        }

        /// <summary>
        /// 控件地址栏的宽度
        /// </summary>
        private int _HexAddressWidth;
        public int HexAddressWidth
        {
            get
            {
                return _HexAddressWidth;
            }
            set
            {
                _HexAddressWidth = value;
            }
        }

        /// <summary>
        /// 控件地址栏地址的显示位数
        /// </summary>
        private AddressBit _HexAddressShowBit;
        public AddressBit HexAddressShowBit
        {
            get
            {
                return _HexAddressShowBit;
            }
            set
            {
                _HexAddressShowBit = value;
            }
        }
        public enum AddressBit
        {
            Bit4 = 1,
            Bit8
        }

        /// <summary>
        /// 控件地址栏地址字体的显示颜色
        /// </summary>
        private Color _HexAddressFontColor;
        public Color HexAddressFontColor
        {
            get
            {
                return _HexAddressFontColor;
            }
            set
            {
                _HexAddressFontColor = value;
            }
        }
        #endregion

        #region 控件单行选择背景框颜色
        /// <summary>
        /// 选择框的上半部分颜色
        /// </summary>
        private Color _HexSelectBorderFColor;
        public Color HexSelectBorderFColor
        {
            get
            {
                return _HexSelectBorderFColor;
            }
            set
            {
                _HexSelectBorderFColor = value;
            }
        }

        /// <summary>
        /// 选择框的下半部分颜色
        /// </summary>
        private Color _HexSelectBorderSColor;
        public Color HexSelectBorderSColor
        {
            get
            {
                return _HexSelectBorderSColor;
            }
            set
            {
                _HexSelectBorderSColor = value;
            }
        }

        /// <summary>
        /// 选择框的外部线条颜色
        /// </summary>
        private Color _HexSelectBorderOLColor;
        public Color HexSelectBorderOLColor
        {
            get
            {
                return _HexSelectBorderOLColor;
            }
            set
            {
                _HexSelectBorderOLColor = value;
            }
        }
        #endregion

        #region 右键菜单属性
        /// <summary>
        /// 用于判定是否显示右键菜单
        /// </summary>
        private bool _IsSupportDisplayMenu;
        public bool IsSupportDisplayMenu
        {
            get
            {
                return _IsSupportDisplayMenu;
            }
            set
            {
                _IsSupportDisplayMenu = value;
            }
        }
        #endregion
    }
}

新建HexEdit.cs文件,将以下代码拷贝至该文件

using System;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.IO;

namespace TestHexEdit
{
    public class HexEdit : Control
    {
        #region 私有变量
        //控件属性
        private HexEditProperties hep;

        //当前实际显示的起始行数
        private int i_start_display = 0;

        //每行显示的数据个数
        private int i_row_display = 16;

        //每行中字符间的间隔
        private int i_row_staff = 10;
        //每列中字符间的间隔
        private int i_Column_staff = 5;

        // 摘要:
        //      HexEdit控件显示的数据
        private string m_HexEditData = null;

        // 摘要:
        //      HexEdit控件中鼠标选择的数据位置
        private POS m_HexMousePos;
        private struct POS
        {
            public int iPos;
            public int iArea;
            public bool bLeftPos;
            public bool bRightPos;
        }

        //下拉控件的宽度
        private int i_Scroll_Width = 15;

        //当前选中的行
        private int i_Select_Row = -1;

        // 摘要:
        //      垂直滚动条
        private VScrollBar m_VScrollBar;

        // 摘要:
        //      是否创建了Caret
        private bool m_IsCreateCaret = false;
        // 摘要:
        //      是否隐藏了Caret
        private bool m_IsHideCaret = false;

        // 摘要:
        //      菜单
        private ContextMenu m_HexMenu;
        private MenuItem m_HexMenuItem0;
        private MenuItem m_HexMenuItem1;
        private MenuItem m_HexMenuItem2;
        private MenuItem m_HexMenuItem3;
        private MenuItem m_HexMenuItem4;

        #endregion

        #region 默认构造函数
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public HexEdit()
        {
            //设置窗体Style
            this.SetStyle(ControlStyles.UserPaint, true);               //支持用户重绘窗体
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);    //在内存中先绘制界面
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);   //双缓冲,防止绘制时抖动
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.UpdateStyles();

            //创建控件属性
            hep = new HexEditProperties();          
  
            //设置位置属性
            m_HexMousePos = new POS();
            m_HexMousePos.iPos = -1;
            m_HexMousePos.iArea = -1;
            m_HexMousePos.bLeftPos = false;
            m_HexMousePos.bRightPos = false;

            //初始化垂直滚动条
            m_VScrollBar = new System.Windows.Forms.VScrollBar();
            m_VScrollBar.Visible = false;
            m_VScrollBar.Enabled = false;
            m_VScrollBar.Width = i_Scroll_Width;
            m_VScrollBar.Minimum = 0;
            m_VScrollBar.Maximum = 0;
            m_VScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(m_VScrollBar_Scroll);            
            this.Controls.Add(m_VScrollBar);

            //初始化菜单            
            m_HexMenu = new ContextMenu();
            m_HexMenuItem0 = new MenuItem();
            m_HexMenuItem0.Text = "Insert a string...";
            m_HexMenuItem0.Name = "string";
            m_HexMenuItem0.Click += new System.EventHandler(MenuItem0_Click);

            m_HexMenuItem1 = new MenuItem();
            m_HexMenuItem1.Text = "Paste a string from clipboard";
            m_HexMenuItem1.Name = "paste";
            m_HexMenuItem1.Click += new System.EventHandler(MenuItem1_Click);

            m_HexMenuItem2 = new MenuItem();
            m_HexMenuItem2.Text = "Load from file...";
            m_HexMenuItem2.Name = "Load";
            m_HexMenuItem2.Click += new System.EventHandler(MenuItem2_Click);

            m_HexMenuItem3 = new MenuItem();
            m_HexMenuItem3.Text = "Save to file...";
            m_HexMenuItem3.Name = "save";
            m_HexMenuItem3.Click += new System.EventHandler(MenuItem3_Click);

            m_HexMenuItem4 = new MenuItem();
            m_HexMenuItem4.Text = "Clear this memory block";
            m_HexMenuItem4.Name = "clear";
            m_HexMenuItem4.Click += new System.EventHandler(MenuItem4_Click);

            m_HexMenu.MenuItems.Add(m_HexMenuItem0);
            m_HexMenu.MenuItems.Add(m_HexMenuItem1);
            m_HexMenu.MenuItems.Add("-");
            m_HexMenu.MenuItems.Add(m_HexMenuItem2);
            m_HexMenu.MenuItems.Add(m_HexMenuItem3);
            m_HexMenu.MenuItems.Add("-");
            m_HexMenu.MenuItems.Add(m_HexMenuItem4);
        }

        /// <summary>
        /// 默认析构函数
        /// </summary>
        ~HexEdit()
        {
            if (m_IsCreateCaret)
            {
                DestroyCaret();
            }
        }
        #endregion

        #region 动态修改控件属性
        /// <summary>
        /// 获取或者设置控件属性
        /// </summary>
        public HexEditProperties HEProperties
        {
            get
            {
                return hep;
            }
            set
            {
                hep = value;
            }
        }
        #endregion

        #region 控件绘画函数
        /// <summary>
        /// 重载绘制函数
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            //设置窗体的背景色
            this.BackColor = hep.HexBackgroundColor;
            this.Focus();            

            //判定是否需要绘制头部
            if (hep.IsSupportDisplayHexHead)
            {
                OnDrawHexEditHead(e);
            }            

            //判定是否需要绘制地址栏
            if (hep.IsSupportHexAddress)
            {
                OnDrawHexEditAddress(e);
            }            

            //绘制数据区域
            OnDrawHexEditData(e);

            //绘制选择框
            OnDrawHexEditAddressSelectEdit(e);

            //绘制外部线条
            OnDrawEditOutLine(e);
        }

        /// <summary>
        /// 绘制外部线条
        /// </summary>
        /// <param name="e"></param>
        private void OnDrawEditOutLine(PaintEventArgs e)
        {
            Point[] pt = { new Point(0, 0),
                           new Point(this.Width, 0),
                           new Point(this.Width, this.Height),
                           new Point(0, this.Height),
                           new Point(0, 0) };

            Pen pen = new Pen(hep.HexOutLineColor, hep.HexOutLineWidth);

            e.Graphics.DrawLines(pen, pt);
        }

        /// <summary>
        /// 绘制HexEdit的头部
        /// </summary>
        /// <param name="e"></param>
        private void OnDrawHexEditHead(PaintEventArgs e)
        {
            //判定起始点
            Point pt = new Point(hep.HexOutLineWidth / 2, hep.HexOutLineWidth / 2);

            //获得绘制实际的宽度
            int width = this.Width - hep.HexOutLineWidth;

            //获得Head的宽度(每个线条占用1的高度)
            int height = hep.HexHeadHeight - 3;

            //绘制Head上半部分
            Brush brush_top = new SolidBrush(hep.HexHeadBackgroundTopColor);
            Rectangle headrt = new Rectangle(pt.X, pt.Y, width, height / 2);
            e.Graphics.FillRectangle(brush_top, headrt);
            pt.Y += height / 2;

            //绘制Head下半部分
            Brush brush_bottom = new SolidBrush(hep.HexHeadBackgroundBottomColor);
            headrt = new Rectangle(pt.X, pt.Y, width, height - height / 2);
            e.Graphics.FillRectangle(brush_bottom, headrt);
            pt.Y += height - height / 2;

            //绘制第一条线
            Pen pen_f = new Pen(hep.HexHeadBackgroundBottomFLineColor);
            e.Graphics.DrawLine(pen_f, pt, new Point(width, pt.Y));
            pt.Y += 1;

            //绘制第二条线
            Pen pen_s = new Pen(hep.HexHeadBackgroundBottomSLineColor);
            e.Graphics.DrawLine(pen_s, pt, new Point(width, pt.Y));
            pt.Y += 1;

            //绘制第三条线
            Pen pen_t = new Pen(hep.HexHeadBackgroundBottomTLineColor);
            e.Graphics.DrawLine(pen_t, pt, new Point(width, pt.Y));
            pt.Y += 1;

            //计算字体实际占用的大小            
            int i_font_width = GetFontSizeFWidth();

            //设置字体的起始位置
            int i_offset = hep.HexOutLineWidth / 2 + i_row_staff;
            if (hep.IsSupportHexAddress)
            {
                i_offset += hep.HexAddressWidth;
            }

            //绘制标尺及字体
            Point pt1 = new Point();
            Point pt2 = new Point();
            Brush brush_staff = new SolidBrush(hep.HexHeadFontColor);
            Pen pen_staff = new Pen(hep.HexHeadStaffColor);
            for (int i = 0; i < i_row_display; i++)
            {
                //绘制数据
                string strMsg = i.ToString("X2");
                pt1.X = i_offset;
                pt1.Y = height / 5;
                e.Graphics.DrawString(strMsg, hep.HexBackgroundFont, brush_staff, pt1);

                //绘制标尺
                pt1.X += i_font_width / 2;
                pt1.Y += hep.HexBackgroundFont.Height - 4;
                pt2.X = pt1.X;
                pt2.Y = pt1.Y + 2;
                e.Graphics.DrawLine(pen_staff, pt1, pt2);

                i_offset += i_font_width + i_row_staff;               
            }              
        }

        /// <summary>
        /// 绘制HexEdit的地址栏
        /// </summary>
        /// <param name="e"></param>
        private void OnDrawHexEditAddress(PaintEventArgs e)
        {
            //如果数据为空,则直接返回
            if (m_HexEditData == null)
            {
                return;
            }

            //判定起始点
            Point pt = GetAddressAreaStartPos();

            //计算控件最大可显示的行数            
            int iMaxDataRow = GetControlMaxRowShowCount();

            //设置背景框
            Brush bgbrush = new SolidBrush(hep.HexAddressBackgroundColor);

            //设置字体
            Brush fontbrush = new SolidBrush(hep.HexAddressFontColor);

            //计算实际数据可显示的行数
            int i_data_row = GetDataNeedDisplayRowShowCount();

            //计算字体的显示高度                       
            int i_font_height = GetFontSizeFHeigth();

            //计算实际起始写的位置
            int i_offset = 0;
            SizeF sizef_add;
            if (hep.HexAddressShowBit == HexEditProperties.AddressBit.Bit4)
            {
                sizef_add = CalcFontSize("0000", hep.HexBackgroundFont);                
            }
            else
            {
                sizef_add = CalcFontSize("00000000", hep.HexBackgroundFont);
            }

            if (hep.HexAddressWidth < (int)(sizef_add.Width + 1))
            {
                hep.HexAddressWidth = (int)(sizef_add.Width + 1);
            }

            i_offset = hep.HexAddressWidth - (int)(sizef_add.Width + 1);

            //设置绘制区域
            Rectangle art = new Rectangle();
            Point pt1 = new Point();
            string strMsg = null;
            for (int ix = i_start_display; ix < i_start_display + iMaxDataRow; ix++)
            {
                if (i_data_row <= ix)
                {
                    break;
                }

                art.X = pt.X;
                art.Y = pt.Y + (ix - i_start_display) * (i_font_height + i_Column_staff);
                art.Width = hep.HexAddressWidth;
                art.Height = i_font_height + i_Column_staff;

                e.Graphics.FillRectangle(bgbrush, art);

                pt1.X = art.X + i_offset;
                pt1.Y = art.Y + (i_font_height + i_Column_staff) / 4;
                if (hep.HexAddressShowBit == HexEditProperties.AddressBit.Bit4)
                {
                    strMsg = (ix * i_row_display).ToString("X4");
                }
                else
                {
                    strMsg = (ix * i_row_display).ToString("X8");
                }
                e.Graphics.DrawString(strMsg, hep.HexBackgroundFont, fontbrush, pt1);
            }
        }

        /// <summary>
        /// 绘制数据区
        /// </summary>
        /// <param name="e"></param>
        private void OnDrawHexEditData(PaintEventArgs e)
        {
            //如果数据为空,则直接返回
            if (m_HexEditData == null)
            {
                return;
            }

            //判定起始点            
            Point pt = GetDataAreaStartPos();

            //计算字体的高度及宽度            
            int i_font_width = GetFontSizeFWidth();
            int i_font_height = GetFontSizeFHeigth();

            //计算控件最大可显示的行数            
            int iMaxDataRow = GetControlMaxRowShowCount();

            //设置字体
            Brush fontbrush = new SolidBrush(hep.HexDataFontColor);

            //计算实际数据可显示的行数
            int i_data_row = GetDataNeedDisplayRowShowCount();            

            //设置绘制区域            
            Point pt1 = new Point();
            string strMsg = null;
            int i_data_offset = i_start_display * i_row_display;
            int iHeight = pt.Y + (i_font_height + i_Column_staff) / 4;
            for (int ix = i_start_display; ix < i_start_display + iMaxDataRow; ix++)
            {
                if (i_data_row <= ix)
                {
                    break;
                }

                pt1.X = pt.X + i_row_staff;
                pt1.Y = iHeight;

                for (int iy = i_data_offset; iy < i_data_offset + i_row_display; iy++)
                {
                    if (iy >= GetDataLength())
                    {
                        break;
                    }

                    strMsg = GetDataByPos(iy).ToString("X2");

                    e.Graphics.DrawString(strMsg, hep.HexBackgroundFont, fontbrush, pt1);

                    pt1.X += i_font_width + i_row_staff;
                }

                i_data_offset += i_row_display;
                iHeight += i_font_height + i_Column_staff;
            }
        }

        /// <summary>
        /// 绘制选择行的背景色
        /// </summary>
        /// <param name="e"></param>
        private void OnDrawHexEditAddressSelectEdit(PaintEventArgs e)
        {
            if (i_Select_Row == -1)
            {
                return;
            }

            //判定起始点
            Point pt = GetAddressAreaStartPos();

            //计算行高            
            int i_font_width = GetFontSizeFWidth();
            int i_font_height = GetFontSizeFHeigth();

            Rectangle rect = new Rectangle();
            rect.X = pt.X;
            rect.Y = pt.Y + i_Select_Row * (i_font_height + i_Column_staff);
            rect.Width = this.Width - hep.HexOutLineWidth;
            rect.Height = i_font_height + i_Column_staff;

            //填充区域
            //LinearGradientBrush lgbrush = new LinearGradientBrush(rect, hep.HexSelectBorderFColor, hep.HexSelectBorderSColor, LinearGradientMode.Vertical);
            //lgbrush.SetSigmaBellShape(0.5f);
            Brush lgbrush = new SolidBrush(Color.FromArgb(150, hep.HexSelectBorderSColor));
            e.Graphics.FillRectangle(lgbrush, rect);

            //绘制外线
            e.Graphics.DrawRectangle(new Pen(hep.HexSelectBorderOLColor, 1), rect);
        }
        #endregion

        #region 重写函数

        // 摘要:
        //      重载消息处理函数,该函数不处理WM_ERASEBKGRND消息
        protected override void WndProc(ref Message m)
        {
            //0x00000014   WM_ERASEBKGRND
            if (m.Msg == 0x00000014)
            {
                return;
            }

            base.WndProc(ref m);
        }

        // 摘要:
        //      处理键盘输入键消息
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
            {
                if (keyData >= Keys.D0 && keyData <= Keys.F ||
                    keyData >= Keys.NumPad0 && keyData <= Keys.NumPad9)
                {
                    byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);
                    byte b = 0;
                    byte c = 0;

                    this.Focus();

                    if (m_HexMousePos.iPos < bt.Length)
                    {
                        if (m_HexMousePos.bLeftPos)
                        {
                            c = (byte)(bt[m_HexMousePos.iPos] & 0x0F);
                            b = HexCharValue((byte)keyData);
                        }

                        if (m_HexMousePos.bRightPos)
                        {
                            b = (byte)((bt[m_HexMousePos.iPos] & 0xF0) >> 4);
                            c = HexCharValue((byte)keyData);
                        }

                        bt[m_HexMousePos.iPos] = (byte)((b << 4) | c);

                        m_HexEditData = ConvertByteToStirng(bt, hep.HexDataType);

                        this.Invalidate();

                        OnVK_Right();
                    }

                    return true;                                      
                }
                else
                {
                    switch (keyData)
                    {
                        case Keys.Up:
                            OnVK_Up();
                            break;
                        case Keys.Down:
                            OnVK_Down();
                            break;
                        case Keys.Left:
                            OnVK_Left();
                            break;
                        case Keys.Right:
                            OnVK_Right();
                            break;
                    }
                }

                return true;
            }
            else
            {
                return base.ProcessCmdKey(ref msg, keyData);
            }
        }
        #endregion

        #region 消息事件函数
        /// <summary>
        /// 响应鼠标按下消息
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            //如果数据为空,则直接返回
            if (m_HexEditData == null)
            {
                return;
            }

            //只响应这两个消息
            if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
            {
                //记录鼠标的坐标
                Point mouse_pt = new Point(e.X, e.Y);

                #region 变量计算
                //判定起始点
                Point pt = GetAddressAreaStartPos();

                //获取字体的高度及宽度
                int i_font_width = GetFontSizeFWidth();
                int i_font_height = GetFontSizeFHeigth();

                //计算控件最大可显示的行数                    
                int iMaxDataRow = GetControlMaxRowShowCount();

                //计算实际数据可显示的行数
                int i_data_row = GetDataNeedDisplayRowShowCount();
                #endregion

                #region 判定是否在当前行中
                //判定是否在当前行中
                Rectangle rect = new Rectangle();
                Region rg;
                int iHeight = pt.Y;
                for (int ix = i_start_display; ix < i_start_display + iMaxDataRow; ix++)
                {
                    if (i_data_row <= ix)
                    {
                        //表明没有选中行
                        i_Select_Row = -1;

                        break;
                    }

                    rect.X = pt.X;
                    rect.Y = iHeight;
                    rect.Width = this.Width - hep.HexOutLineWidth;
                    rect.Height = i_font_height + i_Column_staff;
                    rg = new Region(rect);
                    if (rg.IsVisible(mouse_pt))
                    {
                        //表明选中了某一行
                        i_Select_Row = ix - i_start_display;
                        this.Invalidate();
                        break;
                    }

                    iHeight += i_font_height + i_Column_staff;
                }

                if(i_Select_Row == -1)
                {
                    //没有选中行
                    return;
                }
                #endregion

                #region 设置显示
                //需要判定是否在Data区域
                //计算Data区域的起始位置
                Point pt_data;
                int i_offset = 0;
                if (hep.IsSupportHexAddress)
                {
                    i_offset = hep.HexOutLineWidth / 2 + hep.HexAddressWidth;
                }
                else
                {
                    i_offset = hep.HexOutLineWidth / 2;
                }
                pt_data = new Point(i_offset, pt.Y);

                rect.X = pt_data.X;
                rect.Y = pt_data.Y + i_Select_Row * (i_font_height + i_Column_staff);
                rect.Width = i_row_display * (i_row_staff + i_font_width);
                rect.Height = i_font_height + i_Column_staff; 
                rg = new Region(rect);
                if (rg.IsVisible(mouse_pt))
                {
                    //表明在Data区域
                    
                    //如果没有创建Caret,则创建
                    OnCreateCaret();

                    int i_data_offset = rect.X + i_row_staff;
                    int i_data_height = rect.Y;

                    for (int iy = 0; iy < i_row_display; iy++)
                    {
                        rect.X = i_data_offset;
                        rect.Y = i_data_height;
                        rect.Width = i_font_width / 2;
                        rect.Height = i_font_height + i_Column_staff;
                        rg = new Region(rect);
                        if (rg.IsVisible(mouse_pt))
                        {
                            SetCaretPos(rect.X, rect.Y);
                            ShowCaret(this.Handle);
                            m_IsHideCaret = false;

                            ShowRightMouseMeun(e, mouse_pt);

                            m_HexMousePos.iPos = (i_start_display + i_Select_Row) * i_row_display + iy;
                            m_HexMousePos.iArea = 1;
                            m_HexMousePos.bLeftPos = true;
                            m_HexMousePos.bRightPos = false;

                            break;
                        }

                        rect.X += i_font_width / 2;
                        //rect.Width = i_font_width - i_font_width / 2;
                        rect.Width = i_font_width - i_font_width / 2 + i_row_staff;
                        rg = new Region(rect);
                        if (rg.IsVisible(mouse_pt))
                        {
                            SetCaretPos(rect.X, rect.Y);
                            ShowCaret(this.Handle);
                            m_IsHideCaret = false;

                            ShowRightMouseMeun(e, mouse_pt);

                            m_HexMousePos.iPos = (i_start_display + i_Select_Row) * i_row_display + iy;
                            m_HexMousePos.iArea = 1;
                            m_HexMousePos.bLeftPos = false;
                            m_HexMousePos.bRightPos = true;

                            break;
                        }

                        i_data_offset += i_font_width + i_row_staff;
                    }

                    //如果点击区域超过最大值,则不显示
                    if (m_HexMousePos.iPos != -1 &&
                        m_HexMousePos.iPos >= GetDataLength())
                    {
                        OnHideCaret();
                    }
                }
                else
                {
                    OnHideCaret();
                }
                #endregion
            }
        }

        /// <summary>
        /// 处理鼠标按键弹起消息
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            //如果数据为空,则直接返回
            if (m_HexEditData == null)
            {
                return;
            }

            this.Focus();
            return;
        }

        // 摘要:
        //      处理垂直拉条的移动
        private void m_VScrollBar_Scroll(object obj, ScrollEventArgs e)
        {
            if (i_start_display != e.NewValue)
            {
                i_start_display = e.NewValue;

                if (!m_IsHideCaret)
                {
                    OnHideCaret();
                    m_IsHideCaret = true;
                }

                m_HexMousePos.iPos = -1;
                m_HexMousePos.iArea = -1;
                m_HexMousePos.bLeftPos = false;
                m_HexMousePos.bRightPos = false;

                this.Invalidate();
            }
        }

        /// <summary>
        /// 实现鼠标中间按钮滚动
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            //表明像下滚动
            if (e.Delta == -120)
            {
                if (i_start_display < this.m_VScrollBar.Maximum)
                {
                    i_start_display += 1;
                    this.m_VScrollBar.Value = i_start_display;
                    this.Invalidate();
                }
            }
            //表明向上滚动
            else if (e.Delta == 120)
            {
                if (i_start_display > 0)
                {
                    i_start_display -= 1;
                    this.m_VScrollBar.Value = i_start_display;
                    this.Invalidate();
                }
            }
            else
            {
                base.OnMouseWheel(e);
            }

            if (!m_IsHideCaret)
            {
                OnHideCaret();
                m_IsHideCaret = true;
            }

            m_HexMousePos.iPos = -1;
            m_HexMousePos.iArea = -1;
            m_HexMousePos.bLeftPos = false;
            m_HexMousePos.bRightPos = false;
        }
        #endregion

        #region 字体相关函数
        /// <summary>
        /// 计算字体的大小
        /// </summary>
        /// <param name="strText"></param>
        /// <param name="font"></param>
        /// <returns></returns>
        private SizeF CalcFontSize(string strText, Font font)
        {
            Graphics g = this.CreateGraphics();
            SizeF sizeF = g.MeasureString(strText, font);
            g.Dispose();

            return sizeF;
        }

        /// <summary>
        /// 获取字体的宽度
        /// </summary>
        /// <returns></returns>
        private int GetFontSizeFWidth()
        {
            SizeF size = CalcFontSize("00", hep.HexBackgroundFont);

            return (int)size.Width + 1;
        }

        /// <summary>
        /// 获取字体的高度
        /// </summary>
        /// <returns></returns>
        private int GetFontSizeFHeigth()
        {
            SizeF size = CalcFontSize("00", hep.HexBackgroundFont);

            return (int)size.Height + 1;
        }
        #endregion

        #region 数据转换函数
        // 摘要:
        //      将一个Hex字符转换为8字节的byte
        private byte HexCharValue(byte b)
        {
            if ('0' <= b && b <= '9')
            {
                return (byte)(b - '0');
            }
            else if ('A' <= b && b <= 'F')
            {
                return (byte)(b - 'A' + 10);
            }
            else if (97 <= b && b <= 105)
            {
                return (byte)(b - 97 + 1);
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 将字符串转换为数组
        /// </summary>
        /// <param name="strData"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        private byte[] ConvertStringToByte(string strData, HexEditProperties.EncodingType dt)
        {
            if (string.IsNullOrEmpty(strData))
            {
                return null;
            }

            if (dt == HexEditProperties.EncodingType.ANSI)
            {
                char[] cData = strData.ToCharArray();
                byte[] bData = new byte[cData.Length];
                for (int ix = 0; ix < cData.Length; ix++)
                {
                    bData[ix] = Convert.ToByte(cData[ix]);
                }
                return bData;
            }
            else if (dt == HexEditProperties.EncodingType.Unicond)
            {
                return Encoding.GetEncoding("Unicode").GetBytes(strData);
            }
            else
            {
                return null;
            }
        }

        // 摘要:
        //      将是byte数组转换成string字符串
        private string ConvertByteToStirng(byte[] bData, HexEditProperties.EncodingType dt)
        {
            if (dt == HexEditProperties.EncodingType.ANSI)
            {
                char[] cData = new char[bData.Length];
                Array.Copy(bData, cData, bData.Length);
                return new string(cData);
            }
            else if (dt == HexEditProperties.EncodingType.Unicond)
            {
                return Encoding.GetEncoding("Unicode").GetString(bData);
            }
            else
            {
                return null;
            }
        }

        // 摘要:
        //      判断传入的char是否为汉字
        private bool IsChineseChar(char character)
        {
            //汉字的范围在4E00 - 9FA5之间,所以只需要判断是否在此空间内即可
            Regex reg = new Regex(@"[\u4e00-\u9fa5]");
            string strData = character.ToString();

            if (reg.IsMatch(strData))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // 摘要:
        //      将是汉字的字符转换成byte数组
        private byte[] ConvertChineseToByte(char character, HexEditProperties.EncodingType dt)
        {
            if (dt == HexEditProperties.EncodingType.ANSI)
            {
                return Encoding.GetEncoding("GB2312").GetBytes(character.ToString());
            }
            else if (dt == HexEditProperties.EncodingType.Unicond)
            {
                return Encoding.GetEncoding("Unicode").GetBytes(character.ToString());
            }
            else
            {
                return null;
            }
        }
        #endregion

        #region 获取位置信息函数
        /// <summary>
        /// 获取控件显示的最大行数
        /// </summary>
        /// <returns></returns>
        private int GetControlMaxRowShowCount()
        {
            //获取字体的宽度及长度
            SizeF sizef = CalcFontSize("00", hep.HexBackgroundFont);
            int i_font_width = (int)sizef.Width + 1;
            int i_font_height = (int)sizef.Height + 1;

            //计算控件最大可显示的行数    
            int i_height = 0;
            if (hep.IsSupportDisplayHexHead)
            {
                i_height = this.Height - hep.HexOutLineWidth - hep.HexHeadHeight;
            }
            else
            {
                i_height = this.Height - hep.HexOutLineWidth;
            }

            int iMaxDataRow = (int)(i_height / (i_font_height + i_Column_staff));

            return iMaxDataRow;
        }

        /// <summary>
        /// 获取数据需要显示的行数
        /// </summary>
        /// <returns></returns>
        private int GetDataNeedDisplayRowShowCount()
        {
            if (string.IsNullOrEmpty(m_HexEditData))
            {
                return -1;
            }

            //计算实际的行数
            int i_data_row = 0;
            int i_data_mod = 0;

            //将数据转换为数组
            byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);

            //将字符串转换为数组                            
            if (bt != null && bt.Length > 0)
            {
                i_data_row = bt.Length / i_row_display;
                i_data_mod = bt.Length % i_row_display;
            }

            if (i_data_mod != 0)
            {
                i_data_row += 1;
            }

            return i_data_row;
        }

        /// <summary>
        /// 获取数据的长度
        /// </summary>
        /// <returns></returns>
        private int GetDataLength()
        {
            if (string.IsNullOrEmpty(m_HexEditData))
            {
                return -1;
            }

            //将数据转换为数组
            byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);

            return bt.Length;
        }

        /// <summary>
        /// 获取指定位置的数据
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        private byte GetDataByPos(int pos)
        {
            //将数据转换为数组
            byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);

            return bt[pos];
        }        

        /// <summary>
        /// 获取所在位置
        /// </summary>
        /// <returns></returns>
        private int GetColumnPos()
        {
            //查找在第几列
            int iColumn = 0;
            if (m_HexMousePos.iPos % i_row_display != 0)
            {
                iColumn = m_HexMousePos.iPos % i_row_display;
            }
            else
            {
                iColumn = 0;
            }

            return iColumn;
        }

        /// <summary>
        /// 获取数据数据所在行的起始位置
        /// </summary>
        /// <returns></returns>
        private Point GetDataAtRowStartPos()
        {
            Point pt_row;
            int i_offset = 0;
            int i_font_height = GetFontSizeFHeigth();

            if (hep.IsSupportHexAddress)
            {
                i_offset = hep.HexOutLineWidth / 2 + hep.HexAddressWidth;
            }
            else
            {
                i_offset = hep.HexOutLineWidth / 2;
            }

            int height = 0;
            if (hep.IsSupportDisplayHexHead)
            {
                height = hep.HexOutLineWidth / 2 + hep.HexHeadHeight + i_Select_Row * (i_font_height + i_Column_staff);
            }
            else
            {
                height = hep.HexOutLineWidth / 2 + i_Select_Row * (i_font_height + i_Column_staff);
            }

            pt_row = new Point(i_offset, height);

            return pt_row;
        }

        /// <summary>
        /// 获取地址栏的起始位置
        /// </summary>
        /// <returns></returns>
        private Point GetAddressAreaStartPos()
        {
            Point pt;            

            if (hep.IsSupportDisplayHexHead)
            {
                pt = new Point(hep.HexOutLineWidth / 2, hep.HexHeadHeight + hep.HexOutLineWidth / 2);                
            }
            else
            {
                pt = new Point(hep.HexOutLineWidth / 2, hep.HexOutLineWidth / 2);                
            }

            return pt;
        }

        /// <summary>
        /// 获取数据区域的起始位置
        /// </summary>
        /// <returns></returns>
        private Point GetDataAreaStartPos()
        {
            Point pt;            
            int i_pt_width = 0;
            int i_pt_height = 0;

            //判定是否显示Head栏
            if (hep.IsSupportDisplayHexHead)
            {
                i_pt_height = hep.HexHeadHeight + hep.HexOutLineWidth / 2;                
            }
            else
            {
                i_pt_height = hep.HexOutLineWidth / 2;                
            }
            //判定是否支持显示地址栏
            if (hep.IsSupportHexAddress)
            {
                i_pt_width = hep.HexAddressWidth + hep.HexOutLineWidth / 2;
            }
            else
            {
                i_pt_width = hep.HexOutLineWidth / 2;
            }

            pt = new Point(i_pt_width, i_pt_height);

            return pt;
        }

        /// <summary>
        /// 获取数据区域的高度
        /// </summary>
        /// <returns></returns>
        private int GetDataAreaHeight()
        {
            int i_height = 0;

            if (hep.IsSupportDisplayHexHead)
            {
                i_height = this.Height - hep.HexOutLineWidth - hep.HexHeadHeight;
            }
            else
            {
                i_height = this.Height - hep.HexOutLineWidth;
            }

            return i_height;
        }
        #endregion

        #region 垂直滚动条显示函数
        /// <summary>
        /// 判定垂直滚动条是否需要显示
        /// </summary>
        private void VScrollBarDisplay()
        {
            //判定起始点            
            Point pt = GetDataAreaStartPos();

            //计算控件最大可显示的行数            
            SizeF sizef = CalcFontSize("00", hep.HexBackgroundFont);
            int i_font_width = GetFontSizeFWidth();
            int i_font_height = GetFontSizeFHeigth();
            int iMaxDataRow = GetControlMaxRowShowCount();

            //计算实际数据可显示的行数
            int i_data_row = GetDataNeedDisplayRowShowCount();

            if (i_data_row > iMaxDataRow)
            {
                this.m_VScrollBar.Visible = true;
                this.m_VScrollBar.Enabled = true;

                //设置控件位置
                this.m_VScrollBar.Location = new Point(this.Width - hep.HexOutLineWidth - i_Scroll_Width, pt.Y);
                this.m_VScrollBar.Size = new Size(i_Scroll_Width, GetDataAreaHeight());

                //设置控件的最大值
                this.m_VScrollBar.LargeChange = 1;
                //this.m_VScrollBar.Maximum = i_data_row / iMaxDataRow + i_data_row % iMaxDataRow;
                this.m_VScrollBar.Maximum = i_data_row - iMaxDataRow;
            }
            else
            {
                this.m_VScrollBar.Visible = false;
                this.m_VScrollBar.Enabled = false;
            }
        }        
        #endregion

        #region Caret函数
        // 摘要:
        //      创建Caret
        private void OnCreateCaret()
        {
            //如果没有创建Caret,则创建
            if (!m_IsCreateCaret)
            {
                m_IsCreateCaret = true;
                CreateCaret(this.Handle, IntPtr.Zero, (int)hep.HexBackgroundFont.Size, hep.HexBackgroundFont.Height + i_Column_staff);
            }
        }

        // 摘要:
        //      隐藏Caret,并设置相关位置
        private void OnHideCaret()
        {
            if (!m_IsHideCaret)
            {
                HideCaret(this.Handle);
                m_IsHideCaret = true;
            }
            m_HexMousePos.iPos = -1;
            m_HexMousePos.iArea = -1;
            m_HexMousePos.bLeftPos = false;
            m_HexMousePos.bRightPos = false;
        }

        // 摘要:
        //      重新生成Caret
        private void CreateNewCaret()
        {
            //获取列
            int iColumn = GetColumnPos();
            //获取字体宽度及高度            
            int i_font_Height = GetFontSizeFHeigth();
            int i_font_Width = GetFontSizeFWidth();
            //获取所在行的起始位置
            Point pt = GetDataAtRowStartPos();

            //如果创建了Caret,则销毁
            if (m_IsCreateCaret)
            {
                DestroyCaret();
                m_IsCreateCaret = false;
            }

            //创建Caret
            OnCreateCaret();
            m_IsCreateCaret = true;

            int iWidth = 0;
            if (m_HexMousePos.bLeftPos)
            {
                iWidth = pt.X + iColumn * (i_font_Width + i_row_staff) + i_row_staff;
            }
            else
            {
                iWidth = pt.X + iColumn * (i_font_Width + i_row_staff) + i_row_staff + i_font_Width / 2;
            }

            //设置位置
            SetCaretPos(iWidth, pt.Y);
            ShowCaret(this.Handle);
        }
        #endregion

        #region 方向键函数
        // 摘要:
        //      Caret向左移动
        private void OnVK_Left()
        {
            if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
            {
                this.Focus();

                //表明在Data区
                if (m_HexMousePos.iArea == 1)
                {
                    //获取字体的宽度及长度                    
                    int i_font_width = GetFontSizeFWidth();
                    int i_font_height = GetFontSizeFHeigth();

                    //查找在第几列
                    int iColumn = GetColumnPos();

                    //获取所在行的启动信息
                    Point pt_row = GetDataAtRowStartPos();

                    //表示在每行的起始位置
                    Point pt = new Point();
                    if (iColumn == 0)
                    {
                        //表明在第一个字节的右部
                        if (m_HexMousePos.bRightPos)
                        {
                            pt.X = pt_row.X + i_row_staff;
                            pt.Y = pt_row.Y;
                            m_HexMousePos.bRightPos = false;
                            m_HexMousePos.bLeftPos = true;
                            SetCaretPos(pt.X, pt.Y);

                            this.Invalidate();
                            return;
                        }
                        //表明在第一个字节的左部
                        if (m_HexMousePos.bLeftPos)
                        {
                            if (i_Select_Row > 0)
                            {
                                i_Select_Row -= 1;

                                pt.X = pt_row.X + i_row_display * (i_font_width + i_row_staff) - i_font_width / 2;
                                pt.Y = pt_row.Y - i_font_height - i_Column_staff;
                                m_HexMousePos.iPos -= 1;
                                m_HexMousePos.bRightPos = true;
                                m_HexMousePos.bLeftPos = false;
                                SetCaretPos(pt.X, pt.Y);

                                this.Invalidate();
                                return;
                            }
                            else if (i_Select_Row == 0 && i_start_display > 0)
                            {
                                i_Select_Row = 0;

                                i_start_display -= 1;

                                m_VScrollBar.Value = i_start_display;
                                this.Invalidate();

                                pt.X = pt_row.X + i_row_display * (i_font_width + i_row_staff) - i_font_width / 2;
                                pt.Y = pt_row.Y;
                                m_HexMousePos.iPos -= 1;
                                m_HexMousePos.bRightPos = true;
                                m_HexMousePos.bLeftPos = false;
                                SetCaretPos(pt.X, pt.Y);

                                this.Invalidate();
                                return;
                            }
                        }
                    }
                    //表示不在每行的起始位置
                    else
                    {
                        //表明在字节的右部
                        if (m_HexMousePos.bRightPos)
                        {
                            pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
                            pt.Y = pt_row.Y;
                            m_HexMousePos.bRightPos = false;
                            m_HexMousePos.bLeftPos = true;
                            SetCaretPos(pt.X, pt.Y);

                            this.Invalidate();
                            return;
                        }

                        //表明在字节的左部
                        if (m_HexMousePos.bLeftPos)
                        {
                            pt.X = pt_row.X + (iColumn - 1) * (i_font_width + i_row_staff) + i_row_staff + i_font_width - i_font_width / 2;
                            pt.Y = pt_row.Y;
                            m_HexMousePos.iPos -= 1;
                            m_HexMousePos.bRightPos = true;
                            m_HexMousePos.bLeftPos = false;
                            SetCaretPos(pt.X, pt.Y);

                            this.Invalidate();
                            return;
                        }
                    }
                }
            }
        }

        // 摘要:
        //      Caret向右移动
        private void OnVK_Right()
        {
            if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
            {
                this.Focus();

                //表明在Data区
                if (m_HexMousePos.iArea == 1)
                {
                    //获取字体的宽度及长度                    
                    int i_font_width = GetFontSizeFWidth();
                    int i_font_height = GetFontSizeFHeigth();

                    //查找在第几列
                    int iColumn = GetColumnPos();

                    //获取所在行的启动信息
                    Point pt_row = GetDataAtRowStartPos();

                    //表明在最后一个字节
                    Point pt = new Point();
                    if (iColumn == i_row_display - 1)
                    {
                        //表明在字节的右部
                        if (m_HexMousePos.bRightPos)
                        {
                            //计算控件最大可显示的行数                                
                            int iMaxDataRow = GetControlMaxRowShowCount();

                            //计算实际的行数
                            int i_data_row = GetDataNeedDisplayRowShowCount();

                            if (i_Select_Row < iMaxDataRow - 1)
                            {
                                i_Select_Row++;

                                pt.X = pt_row.X + i_row_staff;
                                pt.Y = pt_row.Y + i_font_height + i_Column_staff;
                                m_HexMousePos.iPos += 1;
                                m_HexMousePos.bRightPos = false;
                                m_HexMousePos.bLeftPos = true;
                                SetCaretPos(pt.X, pt.Y);

                                this.Invalidate();
                                return;
                            }
                            else if (i_Select_Row == iMaxDataRow - 1 && i_data_row - i_start_display - iMaxDataRow > 0)
                            {
                                i_start_display += 1;

                                m_VScrollBar.Value = i_start_display;
                                this.Invalidate();

                                pt.X = pt_row.X + i_row_staff;
                                pt.Y = pt_row.Y;
                                m_HexMousePos.iPos += 1;
                                m_HexMousePos.bRightPos = false;
                                m_HexMousePos.bLeftPos = true;
                                SetCaretPos(pt.X, pt.Y);

                                return;
                            }
                        }

                        //表明在字节的左部
                        if (m_HexMousePos.bLeftPos)
                        {
                            pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
                            pt.Y = pt_row.Y;
                            m_HexMousePos.bRightPos = true;
                            m_HexMousePos.bLeftPos = false;
                            SetCaretPos(pt.X, pt.Y);

                            this.Invalidate();
                            return;
                        }
                    }
                    else
                    {
                        //表明在字节的右部
                        if (m_HexMousePos.bRightPos)
                        {
                            //判定是否在最后一个字节
                            if (m_HexMousePos.iPos + 1 >= GetDataLength())
                            {
                                return;
                            }

                            pt.X = pt_row.X + (iColumn + 1) * (i_font_width + i_row_staff) + i_row_staff;
                            pt.Y = pt_row.Y;
                            m_HexMousePos.iPos += 1;
                            m_HexMousePos.bRightPos = false;
                            m_HexMousePos.bLeftPos = true;
                            SetCaretPos(pt.X, pt.Y);

                            this.Invalidate();
                            return;
                        }

                        //表明在字节的左部
                        if (m_HexMousePos.bLeftPos)
                        {
                            pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
                            pt.Y = pt_row.Y;
                            m_HexMousePos.bRightPos = true;
                            m_HexMousePos.bLeftPos = false;
                            SetCaretPos(pt.X, pt.Y);

                            this.Invalidate();
                            return;
                        }
                    }
                }
            }
        }

        // 摘要:
        //      Caret向下移动
        private void OnVK_Down()
        {
            if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
            {
                this.Focus();

                //表明在Data区
                if (m_HexMousePos.iArea == 1)
                {
                    //获取字体的宽度及长度                    
                    int i_font_width = GetFontSizeFWidth();
                    int i_font_height = GetFontSizeFHeigth();

                    //查找在第几列
                    int iColumn = GetColumnPos();

                    //获取所在行的启动信息
                    Point pt_row = GetDataAtRowStartPos();

                    //计算最大显示行数
                    int iMaxDataRow = GetControlMaxRowShowCount();

                    //计算实际数据可显示的行数
                    int i_data_row = GetDataNeedDisplayRowShowCount();

                    //进行判定
                    Point pt = new Point();
                    if (m_HexMousePos.iPos + i_row_display < GetDataLength())
                    {
                        if (i_Select_Row < iMaxDataRow - 1)
                        {
                            i_Select_Row += 1;

                            //表明在第一个字节的右部
                            if (m_HexMousePos.bRightPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
                                pt.Y = pt_row.Y + i_font_height + i_Column_staff;

                                m_HexMousePos.iPos += i_row_display;
                                m_HexMousePos.bRightPos = true;
                                m_HexMousePos.bLeftPos = false;
                                SetCaretPos(pt.X, pt.Y);

                                this.Invalidate();
                                return;
                            }
                            //表明在第一个字节的左部
                            if (m_HexMousePos.bLeftPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
                                pt.Y = pt_row.Y + i_font_height + i_Column_staff;

                                m_HexMousePos.iPos += i_row_display;
                                m_HexMousePos.bRightPos = false;
                                m_HexMousePos.bLeftPos = true;
                                SetCaretPos(pt.X, pt.Y);

                                this.Invalidate();
                                return;
                            }
                        }
                        else
                        {
                            i_start_display += 1;

                            //表明在第一个字节的右部
                            if (m_HexMousePos.bRightPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
                                pt.Y = pt_row.Y;

                                m_HexMousePos.iPos += i_row_display;
                                m_HexMousePos.bRightPos = true;
                                m_HexMousePos.bLeftPos = false;
                                SetCaretPos(pt.X, pt.Y);

                                this.m_VScrollBar.Value = i_start_display;
                                this.Invalidate();
                                return;
                            }
                            //表明在第一个字节的左部
                            if (m_HexMousePos.bLeftPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
                                pt.Y = pt_row.Y;

                                m_HexMousePos.iPos += i_row_display;
                                m_HexMousePos.bRightPos = false;
                                m_HexMousePos.bLeftPos = true;
                                SetCaretPos(pt.X, pt.Y);

                                this.m_VScrollBar.Value = i_start_display;
                                this.Invalidate();
                                return;
                            }
                        }
                    }
                }
            }
        }

        // 摘要:
        //      Caret向上移动
        private void OnVK_Up()
        {
            if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
            {
                //表明在Data区
                if (m_HexMousePos.iArea == 1)
                {
                    //获取字体的宽度及长度                    
                    int i_font_width = GetFontSizeFWidth();
                    int i_font_height = GetFontSizeFHeigth();

                    //查找在第几列
                    int iColumn = GetColumnPos();

                    //获取所在行的启动信息
                    Point pt_row = GetDataAtRowStartPos();

                    //计算最大显示行数
                    int iMaxDataRow = GetControlMaxRowShowCount();

                    //计算实际数据可显示的行数
                    int i_data_row = GetDataNeedDisplayRowShowCount();

                    //进行判定
                    Point pt = new Point();
                    if (m_HexMousePos.iPos - i_row_display > 0)
                    {
                        if (i_Select_Row > 0)
                        {
                            i_Select_Row -= 1;

                            //表明在第一个字节的右部
                            if (m_HexMousePos.bRightPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
                                pt.Y = pt_row.Y - i_font_height - i_Column_staff;

                                m_HexMousePos.iPos -= i_row_display;
                                m_HexMousePos.bRightPos = true;
                                m_HexMousePos.bLeftPos = false;
                                SetCaretPos(pt.X, pt.Y);

                                this.Invalidate();
                                return;
                            }
                            //表明在第一个字节的左部
                            if (m_HexMousePos.bLeftPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
                                pt.Y = pt_row.Y - i_font_height - i_Column_staff;

                                m_HexMousePos.iPos -= i_row_display;
                                m_HexMousePos.bRightPos = false;
                                m_HexMousePos.bLeftPos = true;
                                SetCaretPos(pt.X, pt.Y);

                                this.Invalidate();
                                return;
                            }
                        }
                        else
                        {
                            i_start_display -= 1;

                            //表明在第一个字节的右部
                            if (m_HexMousePos.bRightPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
                                pt.Y = pt_row.Y;

                                m_HexMousePos.iPos -= i_row_display;
                                m_HexMousePos.bRightPos = true;
                                m_HexMousePos.bLeftPos = false;
                                SetCaretPos(pt.X, pt.Y);

                                this.m_VScrollBar.Value = i_start_display;
                                this.Invalidate();
                                return;
                            }
                            //表明在第一个字节的左部
                            if (m_HexMousePos.bLeftPos)
                            {
                                pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
                                pt.Y = pt_row.Y;

                                m_HexMousePos.iPos -= i_row_display;
                                m_HexMousePos.bRightPos = false;
                                m_HexMousePos.bLeftPos = true;
                                SetCaretPos(pt.X, pt.Y);

                                this.m_VScrollBar.Value = i_start_display;
                                this.Invalidate();
                                return;
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region 公开函数
        /// <summary>
        /// 向控件中添加数据
        /// </summary>
        /// <param name="strData"></param>
        public void AddData(string strData)
        {
            if (string.IsNullOrEmpty(strData))
            {
                return;
            }

            m_HexEditData = strData;

            VScrollBarDisplay();

            this.Invalidate();
        }

        /// <summary>
        /// 向控件中添加数据
        /// </summary>
        /// <param name="strData"></param>
        public void AddData(byte[] bdata)
        {
            if (bdata == null)
            {
                return;
            }

            m_HexEditData = ConvertByteToStirng(bdata, hep.HexDataType);

            VScrollBarDisplay();

            this.Invalidate();
        }

        /// <summary>
        /// 获取控件数据
        /// </summary>
        /// <returns></returns>
        public string GetStringData()
        {
            return m_HexEditData;
        }

        /// <summary>
        /// 获取控件数据
        /// </summary>
        /// <returns></returns>
        public byte[] GetByteArrayData()
        {
            return ConvertStringToByte(m_HexEditData, hep.HexDataType);
        }

        #endregion

        #region 动态加载函数
        [DllImport("user32.dll")]
        static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
        [DllImport("user32.dll")]
        static extern bool ShowCaret(IntPtr hWnd);
        [DllImport("User32.dll")]
        static extern bool HideCaret(IntPtr hWnd);
        [DllImport("User32.dll")]
        static extern bool SetCaretPos(int x, int y);
        [DllImport("user32.dll")]
        static extern bool DestroyCaret();
        #endregion

        #region 菜单响应函数
        // 摘要:
        //      显示右键菜单
        private void ShowRightMouseMeun(MouseEventArgs e, Point pt)
        {
            if (e.Button == MouseButtons.Right && hep.IsSupportDisplayMenu)
            {
                m_HexMenu.Show(this, pt);
            }
        }

        // 摘要:
        //      插入一个string
        private void MenuItem0_Click(object obj, EventArgs e)
        {
            Form f1 = new Form();

            //获取字体的高度及宽度
            int i_font_height = GetFontSizeFHeigth();
            int i_font_width = GetFontSizeFWidth();
            //查找在第几列
            int iColumn = GetColumnPos();
            //获取起始位置
            Point pt = GetDataAtRowStartPos();

            f1.Text = "Insert a string...";
            f1.ShowIcon = false;
            f1.MaximizeBox = false;
            f1.MinimizeBox = false;
            f1.StartPosition = FormStartPosition.Manual;
            f1.FormBorderStyle = FormBorderStyle.FixedDialog;
            f1.Size = new System.Drawing.Size(470, 300);            
            f1.Location = new System.Drawing.Point(pt.X + iColumn * (i_font_width + i_row_staff), pt.Y);

            Label lb = new Label();
            lb.Text = "插入string的长度: ";
            lb.Location = new Point(20, 23);
            lb.Size = new System.Drawing.Size(110, 20);
            lb.Visible = true;
            f1.Controls.Add(lb);

            TextBox tb = new TextBox();
            tb.Location = new System.Drawing.Point(130, 20);
            tb.Size = new System.Drawing.Size(200, 20);
            tb.Visible = true;
            f1.Controls.Add(tb);

            Label lb1 = new Label();
            lb1.Text = "插入string的内容: ";
            lb1.Location = new Point(20, 50);
            lb1.Size = new System.Drawing.Size(110, 20);
            lb1.Visible = true;
            f1.Controls.Add(lb1);

            TextBox tb1 = new TextBox();
            tb1.Location = new System.Drawing.Point(20, 75);
            tb1.Size = new System.Drawing.Size(310, 180);
            tb1.Visible = true;
            tb1.Multiline = true;
            f1.Controls.Add(tb1);

            Button button = new Button();
            button.Text = "OK";
            button.Location = new Point(350, 18);
            button.Size = new System.Drawing.Size(100, 30);
            button.Visible = true;
            button.Click += new System.EventHandler(OK_Click);
            f1.Controls.Add(button);

            Button button1 = new Button();
            button1.Text = "Cancle";
            button1.Location = new Point(350, 50);
            button1.Size = new System.Drawing.Size(100, 30);
            button1.Visible = true;
            button1.Click += new System.EventHandler(CANCLE_Click);
            f1.Controls.Add(button1);

            if (DialogResult.OK == f1.ShowDialog())
            {
                string strLength = tb.Text;
                string strContext = tb1.Text;

                if (string.IsNullOrEmpty(strLength) ||
                    string.IsNullOrEmpty(strContext))
                {
                    return;
                }

                if (uint.Parse(strLength) != strContext.Length)
                {
                    return;
                }

                byte[] bSource = ConvertStringToByte(m_HexEditData, hep.HexDataType);
                byte[] bt = ConvertStringToByte(strContext, hep.HexDataType);

                int i_copy_data_length = 0;
                if (m_HexMousePos.iPos + bt.Length >= bSource.Length)
                {
                    i_copy_data_length = bSource.Length - m_HexMousePos.iPos;
                }
                else
                {
                    i_copy_data_length = bt.Length;
                }

                //拷贝数据
                Array.Copy(bt, 0, bSource, m_HexMousePos.iPos, i_copy_data_length);
                m_HexEditData = ConvertByteToStirng(bSource, hep.HexDataType);
                this.Invalidate();                
            }

            CreateNewCaret();
        }
        // 摘要:
        //      响应弹出FORM的OK/CANCLE按钮
        private void OK_Click(object obj, EventArgs e)
        {
            Button bt = (Button)obj;

            Form f1 = bt.Parent as Form;

            f1.DialogResult = DialogResult.OK;
        }
        private void CANCLE_Click(object obj, EventArgs e)
        {
            Button bt = (Button)obj;

            Form f1 = bt.Parent as Form;

            f1.DialogResult = DialogResult.Cancel;
        }

        // 摘要:
        //      从剪贴板上复制
        private void MenuItem1_Click(object obj, EventArgs e)
        {
            IDataObject ido = Clipboard.GetDataObject();

            if (ido.GetDataPresent(DataFormats.Text))
            {
                string strData = (string)ido.GetData(DataFormats.Text);

                byte[] bSource = ConvertStringToByte(m_HexEditData, hep.HexDataType);
                byte[] bt = ConvertStringToByte(strData, hep.HexDataType);

                int i_copy_data_length = 0;
                if (m_HexMousePos.iPos + bt.Length >= bSource.Length)
                {
                    i_copy_data_length = bSource.Length - m_HexMousePos.iPos;
                }
                else
                {
                    i_copy_data_length = bt.Length;
                }

                //拷贝数据
                Array.Copy(bt, 0, bSource, m_HexMousePos.iPos, i_copy_data_length);
                m_HexEditData = ConvertByteToStirng(bSource, hep.HexDataType);
                this.Invalidate(); 
            }
        }

        // 摘要:
        //      从文件中载入数据
        private void MenuItem2_Click(object obj, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "all file (*.*)|*.*";
            ofd.FilterIndex = 1;
            ofd.RestoreDirectory = true;
            ofd.FileName = null;
            if (DialogResult.OK == ofd.ShowDialog())
            {
                string strFilePath = ofd.FileName;

                byte[] bSource = ConvertStringToByte(m_HexEditData, hep.HexDataType);
                byte[] bt = ReadHexDataFromFile(strFilePath);                                

                int i_copy_data_length = 0;
                if (m_HexMousePos.iPos + bt.Length >= bSource.Length)
                {
                    i_copy_data_length = bSource.Length - m_HexMousePos.iPos;
                }
                else
                {
                    i_copy_data_length = bt.Length;
                }

                //拷贝数据
                Array.Copy(bt, 0, bSource, m_HexMousePos.iPos, i_copy_data_length);
                m_HexEditData = ConvertByteToStirng(bSource, hep.HexDataType);
                this.Invalidate(); 
            }

            CreateNewCaret();
        }
        // 摘要:
        //      从文件中读取十六进制数据流
        private byte[] ReadHexDataFromFile(string path)
        {
            if (!File.Exists(path))
            {
                return null;
            }

            FileStream fs = new FileStream(path, FileMode.Open);
            BinaryReader br = new BinaryReader(fs);

            byte[] bt = br.ReadBytes((int)fs.Length);

            br.Close();

            return bt;
        }

        // 摘要:
        //      将数据保存至文件
        private void MenuItem3_Click(object obj, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "all file (*.*)|*.*";
            sfd.FilterIndex = 1;
            sfd.RestoreDirectory = true;
            sfd.FileName = null;
            if (DialogResult.OK == sfd.ShowDialog())
            {
                byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);

                WriteHexDataToFile(sfd.FileName, bt);
            }

            CreateNewCaret();
        }
        // 摘要:
        //      将数据写入到文件中
        private bool WriteHexDataToFile(string path, byte[] bt)
        {
            if (File.Exists(path))
            {
                if (DialogResult.OK != MessageBox.Show(path + " 文件已经存在,是否替换?"))
                {
                    return false;
                }
            }

            FileStream fs = new FileStream(path, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);

            bw.Write(bt, 0, bt.Length);

            bw.Close();

            return true;
        }

        // 摘要:
        //      清空数据
        private void MenuItem4_Click(object obj, EventArgs e)
        {
            byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);

            for (int ix = 0; ix < bt.Length; ix++)
            {
                bt[ix] = 0;
            }

            m_HexEditData = ConvertByteToStirng(bt, hep.HexDataType);

            this.Invalidate();
        }

        #endregion
    }
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值