C# HexEdit

Just4life發表於2014-12-24

新建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
    }
}