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