1 编写一个Hex Edit控件,使用VS2010建立一个类控件库,分别增加两个类文件,一个命名为HexEdit.cs, 一个命名为TextEditControl.cs,具体内容如下所示:
1)HexEdit.cs
using System.Drawing;
using System.Windows.Forms;
namespace Sense.Test.UIControl
{
// 摘要:
// 在Sense.Test.UIControl中显示一个十六进制控件
public class HexEdit
{
// 摘要:
// 初始化Sense.Test.UIControl.HexEdit类的一个新实例
public HexEdit()
{
_IsShowAddressColumn = false;
_AddressWidth = 100;
_AddressShowBit = AddressBit.Bit8;
_AddressFontColor = Color.Black;
//_AddressBGColor = Color.FromArgb(190, 190, 190);
_AddressBGColor = Color.White;
_IsShowHeadColumn = false;
_HeadHeight = 22;
_HeadFontColor = Color.Black;
_HeadShowBit = HeadBit.Bit32;
_HeadBGColor = Color.FromArgb(240, 240, 240);
_HeadStaffColor = Color.Black;
_IsShowStringColumn = false;
_StringFontColor = Color.Black;
//_StringBGColor = Color.FromArgb(120, 120, 120);
_StringBGColor = Color.White;
//_DataBGColor = Color.FromArgb(150, 150, 150);
_DataBGColor = Color.White;
_DataType = EncodingType.ANSI;
_IsSupportMultiSelect = false;
_IsSupportClickSelect = false;
_BorderLineColor = Color.FromArgb(130, 249, 252);
_BorderBGColor = Color.FromArgb(222, 252, 249);
_IsSupportMenu = false;
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的地址属性
private bool _IsShowAddressColumn;
public bool IsShowAddressColumn
{
get
{
return _IsShowAddressColumn;
}
set
{
_IsShowAddressColumn = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的地址宽度
private int _AddressWidth;
public int AddressWidth
{
get
{
return _AddressWidth;
}
set
{
_AddressWidth = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的地址背景色
private Color _AddressBGColor;
public Color AddressBGColor
{
get
{
return _AddressBGColor;
}
set
{
_AddressBGColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的地址显示位数
private AddressBit _AddressShowBit;
public AddressBit AddressShowBit
{
get
{
return _AddressShowBit;
}
set
{
_AddressShowBit = value;
}
}
public enum AddressBit
{
Bit4 = 1,
Bit8
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的地址字体画刷颜色
private Color _AddressFontColor;
public Color AddressFontColor
{
get
{
return _AddressFontColor;
}
set
{
_AddressFontColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的Head属性
private bool _IsShowHeadColumn;
public bool IsShowHeadColumn
{
get
{
return _IsShowHeadColumn;
}
set
{
_IsShowHeadColumn = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的Head的高度
private int _HeadHeight;
public int HeadHeight
{
get
{
return _HeadHeight;
}
set
{
_HeadHeight = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的Head背景色
private Color _HeadBGColor;
public Color HeadBGColor
{
get
{
return _HeadBGColor;
}
set
{
_HeadBGColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的Head的字体颜色
private Color _HeadFontColor;
public Color HeadFontColor
{
get
{
return _HeadFontColor;
}
set
{
_HeadFontColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的Head的标尺颜色
private Color _HeadStaffColor;
public Color HeadStaffColor
{
get
{
return _HeadStaffColor;
}
set
{
_HeadStaffColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的Head的显示位数
private HeadBit _HeadShowBit;
public HeadBit HeadShowBit
{
get
{
return _HeadShowBit;
}
}
public enum HeadBit
{
Bit16 = 16,
Bit32 = 32
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的字符串属性
private bool _IsShowStringColumn;
public bool IsShowStringColumn
{
get
{
return _IsShowStringColumn;
}
set
{
_IsShowStringColumn = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的字符串字体颜色
private Color _StringFontColor;
public Color StringFontColor
{
get
{
return _StringFontColor;
}
set
{
_StringFontColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的String背景色
private Color _StringBGColor;
public Color StringBGColor
{
get
{
return _StringBGColor;
}
set
{
_StringBGColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的Data背景色
private Color _DataBGColor;
public Color DataBGColor
{
get
{
return _DataBGColor;
}
set
{
_DataBGColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的数据编码格式
private EncodingType _DataType;
public EncodingType DataType
{
get
{
return _DataType;
}
set
{
_DataType = value;
}
}
public enum EncodingType
{
ANSI = 1,
Unicond
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的是否支持多行属性
private bool _IsSupportMultiSelect;
public bool IsSupportMultiSeletc
{
get
{
return _IsSupportMultiSelect;
}
set
{
_IsSupportMultiSelect = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的是否支持单击Adress行选择整行属性
private bool _IsSupportClickSelect;
public bool IsSupportClickSelect
{
get
{
return _IsSupportClickSelect;
}
set
{
_IsSupportClickSelect = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的选择数据时的颜色
private Color _BorderBGColor;
public Color BorderBGColor
{
get
{
return _BorderBGColor;
}
set
{
_BorderBGColor = value;
}
}
private Color _BorderLineColor;
public Color BorderLineColor
{
get
{
return _BorderLineColor;
}
set
{
_BorderLineColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.HexEdit类的是否支持右键显示菜单
private bool _IsSupportMenu;
public bool IsSupportMenu
{
get
{
return _IsSupportMenu;
}
set
{
_IsSupportMenu = value;
}
}
}
}
2)TextEditControl.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Text.RegularExpressions;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace Sense.Test.UIControl
{
public class TextEditControl : Control
{
#region 构造函数
// 摘要:
// 初始化Sense.Test.UIControl.TextEditControl类的一个新实例
public TextEditControl()
{
//设置窗体Style
this.SetStyle(ControlStyles.UserPaint, true); //支持用户重绘窗体
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); //在内存中先绘制界面
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //双缓冲,防止绘制时抖动
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.UpdateStyles();
//外部线条宽度及画笔
_fOutLineWidth = 2;
_OutLinePen = new Pen(Color.FromArgb(0x78, 0x82, 0x8F), _fOutLineWidth);
//背景色
_BackgroundColor = Color.White;
//默认字体
_Font = new Font("Courier New", 12);
//初始化垂直滚动条
m_VScrollBarWidth = 15;
m_VScrollBarPos = 0;
m_VScrollBar = new System.Windows.Forms.VScrollBar();
m_VScrollBar.Visible = false;
m_VScrollBar.Enabled = false;
m_VScrollBar.Minimum = 0;
m_VScrollBar.Maximum = 0;
m_VScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(m_VScrollBar_Scroll);
m_VScrollBar.MouseWheel += new System.Windows.Forms.MouseEventHandler(m_VScrollBar_Mouse_Wheel);
this.Controls.Add(m_VScrollBar);
//默认不支持HexEdit
m_HexEdit = new HexEdit();
HexEdit hexedit = new HexEdit();
hexedit.IsShowHeadColumn = true;
hexedit.IsShowAddressColumn = true;
hexedit.IsShowStringColumn = false;
hexedit.DataType = Sense.Test.UIControl.HexEdit.EncodingType.ANSI;
hexedit.IsSupportClickSelect = true;
hexedit.AddressShowBit = Sense.Test.UIControl.HexEdit.AddressBit.Bit4;
SizeF sizef = CalcFontSize("0000h", _Font);
hexedit.AddressWidth = (int)sizef.Width;
HexEdit(hexedit);
m_HexEditData = null;
m_HexMousePos = new POS();
m_HexMousePos.iPos = -1;
m_HexMousePos.iArea = -1;
m_HexMousePos.bLeftPos = false;
m_HexMousePos.bRightPos = false;
m_AddressPos = -1;
m_IsCreateCaret = false;
m_IsHideCaret = true;
//初始化菜单
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);
//AddHexEditData("12345678123456781234234567812345678123423456781234567812342345678123456781234234567812345678123423456781234567812342345678123456781234234567812345678123423456781234567812342345678123456781234234567812345678123423456781234567812342345678123456781234");
}
#endregion
#region 公开属性
// 摘要:
// 获取/设置Sense.Test.UIControl.TextEditControl类的外部线条宽度
private float _fOutLineWidth;
public float fOutLineWidth
{
get
{
return _fOutLineWidth;
}
set
{
_fOutLineWidth = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.TextEditControl类的外部线条画笔
private Pen _OutLinePen;
public Pen OutLinePen
{
get
{
return _OutLinePen;
}
set
{
_OutLinePen = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.TextEditControl类的背景色
private Color _BackgroundColor;
public Color BackgroundColor
{
get
{
return _BackgroundColor;
}
set
{
_BackgroundColor = value;
}
}
// 摘要:
// 获取/设置Sense.Test.UIControl.TextEditControl类的字体
private Font _Font;
public Font Font
{
get
{
return _Font;
}
set
{
_Font = value;
}
}
// 摘要:
// HexEdit控件显示的数据
private string m_HexEditData;
public string HexEditData
{
get
{
return m_HexEditData;
}
set
{
AddHexEditData(value);
}
}
#endregion
#region 公开函数
// 摘要:
// 添加HexEdit控件
public void HexEdit(HexEdit hexedit)
{
m_HexEdit = hexedit;
}
// 摘要:
// 添加HexEdit要显示的数据
public void AddHexEditData(string strData)
{
m_HexEditData = strData;
if (!m_VScrollBar.Visible)
{
HideVScrollBar();
}
Rectangle rt = CalcEditRectangle();
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
int iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (bt.Length + 1 % (int)m_HexEdit.HeadShowBit != 0)
{
iMaxDataRow += 1;
}
int iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
if (iMaxDataRow * (int)_Font.Height > rt.Height - iHeight)
{
ShowVScrollBar();
}
}
#endregion
#region 窗体绘制函数
// 摘要:
// 绘制Sense.Test.UIControl.TextEditControl控件
protected override void OnPaint(PaintEventArgs e)
{
this.BackColor = _BackgroundColor;
this.Focus();
OnDrawHexEditHead(e);
OnDrawHexEditAddress(e);
OnDrawHexEditData(e);
OnDrawHexEditString(e);
OnDrawHexEditAddressSelectEdit(e);
OnDrawHexEditDataSelectEdit(e);
OnDrawEditOutLine(e);
}
// 摘要:
// 绘制Sense.Test.UIControl.TextEditControl控件的外部线条
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) };
e.Graphics.DrawLines(OutLinePen, pt);
}
// 摘要:
// 绘制Sense.Test.UIControl.TextEditControl控件HexEdit的表头
private void OnDrawHexEditHead(PaintEventArgs e)
{
Rectangle rt = CalcEditRectangle();
int iOffset = 0;
int iStaffCount = 0;
string strMsg = null;
Point pt1 = new Point();
Point pt2 = new Point();
if (m_HexEdit.IsShowHeadColumn)
{
//填充Head背景色
Brush brush = new SolidBrush(m_HexEdit.HeadBGColor);
Rectangle headrt = new Rectangle(rt.X, rt.Y, rt.Width, m_HexEdit.HeadHeight);
e.Graphics.FillRectangle(brush, headrt);
if (m_HexEdit.IsShowAddressColumn)
{
iOffset = m_HexEdit.AddressWidth;
}
//绘制标尺
brush = new SolidBrush(m_HexEdit.HeadFontColor);
pt1.X = rt.X + iOffset;
SizeF sizef = CalcFontSize("00", _Font);
iOffset = pt1.X;
Pen pen = new Pen(m_HexEdit.HeadStaffColor);
iStaffCount = (int)m_HexEdit.HeadShowBit;
for (int ix = 0; ix < iStaffCount; ix++)
{
strMsg = ix.ToString("X2");
pt1.X = iOffset;
pt1.Y = rt.Y + m_HexEdit.HeadHeight - _Font.Height - 2;
if (pt1.X - rt.X >= rt.Width)
{
break;
}
e.Graphics.DrawString(strMsg, _Font, brush, pt1);
pt1.X += (int)sizef.Width / 2;
pt1.Y += _Font.Height - 4;
pt2.X = pt1.X;
pt2.Y = pt1.Y + 5;
e.Graphics.DrawLine(pen, pt1, pt2);
iOffset += (int)sizef.Width;
}
}
}
// 摘要:
// 绘制Sense.Test.UIControl.TextEditControl控件HexEdit的地址栏
private void OnDrawHexEditAddress(PaintEventArgs e)
{
Rectangle rt = CalcEditRectangle();
int iHeight = 0;
int iOffset = 0;
string strMsg = null;
Point pt1 = new Point();
int iMaxDataRow = 0;
if (m_HexEdit.IsShowAddressColumn)
{
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
if (m_HexEditData == null)
{
return;
}
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (bt.Length % (int)m_HexEdit.HeadShowBit != 0)
{
iMaxDataRow += 1;
}
if (m_HexEdit.AddressShowBit == UIControl.HexEdit.AddressBit.Bit4)
{
SizeF sizef = CalcFontSize("0000h", _Font);
if (m_HexEdit.AddressWidth < (int)sizef.Width)
{
m_HexEdit.AddressWidth = (int)sizef.Width;
}
iOffset = m_HexEdit.AddressWidth - (int)sizef.Width;
}
else
{
SizeF sizef = CalcFontSize("00000000h", _Font);
if (m_HexEdit.AddressWidth < (int)sizef.Width)
{
m_HexEdit.AddressWidth = (int)sizef.Width;
}
iOffset = m_HexEdit.AddressWidth - (int)sizef.Width;
}
Brush bgbrush = new SolidBrush(m_HexEdit.AddressBGColor);
Brush fontbrush = new SolidBrush(m_HexEdit.AddressFontColor);
Rectangle art = new Rectangle();
for (int ix = m_VScrollBarPos; ix < iMaxDataRow; ix++)
{
art.X = rt.X;
art.Y = iHeight + (ix - m_VScrollBarPos) * _Font.Height;
art.Width = m_HexEdit.AddressWidth;
art.Height = _Font.Height;
if (art.Y + _Font.Height >= rt.Height)
{
return;
}
e.Graphics.FillRectangle(bgbrush, art);
pt1.X = rt.X + iOffset;
pt1.Y = iHeight + (ix - m_VScrollBarPos) * _Font.Height;
if (m_HexEdit.HeadShowBit == UIControl.HexEdit.HeadBit.Bit16)
{
if (m_HexEdit.AddressShowBit == UIControl.HexEdit.AddressBit.Bit4)
{
strMsg = (ix * 16).ToString("X4") + "h";
}
else
{
strMsg = (ix * 16).ToString("X8") + "h";
}
}
else
{
if (m_HexEdit.AddressShowBit == UIControl.HexEdit.AddressBit.Bit4)
{
strMsg = (ix * 32).ToString("X4") + "h";
}
else
{
strMsg = (ix * 32).ToString("X8") + "h";
}
}
e.Graphics.DrawString(strMsg, _Font, fontbrush, pt1);
}
}
}
// 摘要:
// 绘制Sense.Test.UIControl.TextEditControl控件HexEdit的数据栏
private void OnDrawHexEditData(PaintEventArgs e)
{
Rectangle rt = CalcEditRectangle();
int iHeight = 0;
int iOffset = 0;
string strMsg = null;
Point pt1 = new Point();
int iMaxDataRow = 0;
int iStaffCount = (int)m_HexEdit.HeadShowBit;
int iDataOffset = 0;
if (m_HexEditData == null)
{
return;
}
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (bt.Length + 1 % (int)m_HexEdit.HeadShowBit != 0)
{
iMaxDataRow += 1;
}
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
iOffset = rt.X;
if (m_HexEdit.IsShowAddressColumn)
{
iOffset += m_HexEdit.AddressWidth;
}
SizeF sizef = CalcFontSize("00", _Font);
Brush fontbrush = new SolidBrush(m_HexEdit.StringFontColor);
Brush bgbrush = new SolidBrush(m_HexEdit.DataBGColor);
Rectangle drt = new Rectangle();
//绘制数据
iDataOffset = m_VScrollBarPos * iStaffCount;
for (int ix = m_VScrollBarPos; ix < iMaxDataRow; ix++)
{
pt1.X = rt.X + iOffset;
pt1.Y = iHeight;
//绘制行背景
drt.X = iOffset;
drt.Y = iHeight;
drt.Width = (int)m_HexEdit.HeadShowBit * (int)sizef.Width;
drt.Height = _Font.Height;
e.Graphics.FillRectangle(bgbrush, drt);
for (int iy = iDataOffset; iy < iDataOffset + iStaffCount; iy++)
{
if (iy >= bt.Length)
{
break;
}
strMsg = bt[iy].ToString("X2");
e.Graphics.DrawString(strMsg, _Font, fontbrush, pt1);
pt1.X += (int)sizef.Width;
}
iDataOffset += iStaffCount;
iHeight += _Font.Height;
if (iHeight + _Font.Height >= rt.Height)
{
break;
}
}
}
// 摘要:
// 绘制Sense.Test.UIControl.TextEditControl控件HexEdit的string栏
private void OnDrawHexEditString(PaintEventArgs e)
{
Rectangle rt = CalcEditRectangle();
int iOffset = 0;
SizeF sizef = CalcFontSize("00", _Font);
Point pt1 = new Point();
Brush fontbrush = new SolidBrush(m_HexEdit.StringFontColor);
Brush bgbrush = new SolidBrush(m_HexEdit.StringBGColor);
int iHeight = 0;
int iMaxDataRow = 0;
int iStaffCount = (int)m_HexEdit.HeadShowBit;
int iDataOffset = 0;
string strMsg = null;
int iLoop = 0;
if (m_HexEdit.IsShowStringColumn)
{
if (m_HexEditData == null)
{
return;
}
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (bt.Length % (int)m_HexEdit.HeadShowBit != 0)
{
iMaxDataRow += 1;
}
iOffset = rt.X;
if (m_HexEdit.IsShowAddressColumn)
{
iOffset += m_HexEdit.AddressWidth;
}
iOffset += (int)m_HexEdit.HeadShowBit * (int)sizef.Width;
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
Rectangle drt = new Rectangle();
sizef = CalcFontSize("0000000000000000", _Font);
byte[] bTemp = new byte[16];
iDataOffset = m_VScrollBarPos * iStaffCount;
//绘制数据
for (int ix = m_VScrollBarPos; ix < iMaxDataRow; ix++)
{
drt.X = iOffset;
drt.Y = iHeight;
drt.Width = (int)sizef.Width + 1;
drt.Height = _Font.Height;
e.Graphics.FillRectangle(bgbrush, drt);
pt1.X = iOffset;
pt1.Y = iHeight;
for (int iy = 0; iy < bTemp.Length; iy++)
{
bTemp[iy] = 0;
}
if (bt.Length - iDataOffset >= iStaffCount)
{
Array.Copy(bt, iDataOffset, bTemp, 0, iStaffCount);
iLoop = iStaffCount;
}
else
{
Array.Copy(bt, iDataOffset, bTemp, 0, bt.Length - iDataOffset);
iLoop = bt.Length - iDataOffset;
}
strMsg = null;
if (m_HexEdit.DataType == UIControl.HexEdit.EncodingType.Unicond)
{
strMsg = ConvertByteToStirng(bTemp, m_HexEdit.DataType);
}
else
{
for (int j = 0; j < iLoop; j++)
{
if (bTemp[j] > 0x1F && !(bTemp[j] > 0x7E && bTemp[j] < 0xFF))
{
strMsg += ((char)bTemp[j]).ToString();
}
else
{
strMsg += '.';
}
}
}
e.Graphics.DrawString(strMsg, _Font, fontbrush, pt1);
iDataOffset += iStaffCount;
iHeight += _Font.Height;
if (iHeight + _Font.Height >= rt.Height)
{
break;
}
}
}
}
// 摘要:
// 绘制Sense.Test.UIControl.TextEditControl控件HexEdit选择地址栏后的选择框
private void OnDrawHexEditAddressSelectEdit(PaintEventArgs e)
{
if (m_HexEdit.IsSupportClickSelect)
{
if (m_HexEdit.IsShowAddressColumn && m_AddressPos != -1)
{
Rectangle rt = CalcEditRectangle();
Rectangle rect = new Rectangle();
rect.X = rt.X;
rect.Y = rt.Y + (m_AddressPos - m_VScrollBarPos) * (int)_Font.Height;
if (m_HexEdit.IsShowHeadColumn)
{
rect.Y += m_HexEdit.HeadHeight;
}
rect.Width = rt.Width - m_VScrollBarWidth;
rect.Height = _Font.Height;
/*
LinearGradientBrush lgbrush = new LinearGradientBrush(rect,
m_HexEdit.BorderFirstColor,
m_HexEdit.BorderSecondColor,
LinearGradientMode.Vertical);
*/
Brush lgbrush = new SolidBrush(Color.FromArgb(60, m_HexEdit.BorderBGColor));
e.Graphics.FillRectangle(lgbrush, rect);
e.Graphics.DrawRectangle(new Pen(m_HexEdit.BorderLineColor, 1), rect);
}
}
}
// 摘要:
// 绘制数据选择区域外框
private void OnDrawHexEditDataSelectEdit(PaintEventArgs e)
{
}
#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)
{
//表明是在Hex区域
if (m_HexMousePos.iArea == 1)
{
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
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, m_HexEdit.DataType);
}
else
{
byte[] bt1;
if (m_HexEdit.DataType == UIControl.HexEdit.EncodingType.ANSI)
{
bt1 = new byte[bt.Length + 1];
bt1[bt.Length] = 0;
}
else
{
bt1 = new byte[bt.Length + 2];
bt1[bt.Length] = 0;
bt1[bt.Length + 1] = 0;
}
Array.Copy(bt, bt1, bt.Length);
if (m_HexMousePos.bLeftPos)
{
c = (byte)(bt1[m_HexMousePos.iPos] & 0x0F);
b = HexCharValue((byte)keyData);
}
if (m_HexMousePos.bRightPos)
{
b = (byte)((bt1[m_HexMousePos.iPos] & 0xF0) >> 4);
c = HexCharValue((byte)keyData);
}
bt1[m_HexMousePos.iPos] = (byte)((b << 4) | c);
m_HexEditData = ConvertByteToStirng(bt1, m_HexEdit.DataType);
}
bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
Rectangle rt = CalcEditRectangle();
int iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (m_HexMousePos.bRightPos && m_HexMousePos.iPos == (bt.Length - 1))
{
if ((bt.Length + 1) % (int)m_HexEdit.HeadShowBit == 1)
{
iMaxDataRow += 1;
int iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
if (iMaxDataRow * (int)_Font.Height > rt.Height - iHeight)
{
m_VScrollBarPos++;
ShowVScrollBar();
m_VScrollBar.Value = m_VScrollBarPos;
}
}
}
else
{
m_VScrollBar.Maximum = iMaxDataRow + 8;
}
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;
}
}
}
else if (m_AddressPos != -1)
{
switch (keyData)
{
case Keys.Up:
OnVK_Up();
break;
case Keys.Down:
OnVK_Down();
break;
}
}
return true;
}
#endregion
#region 消息响应函数
// 摘要:
// 处理垂直拉条的移动
private void m_VScrollBar_Scroll(object obj, ScrollEventArgs e)
{
if (m_VScrollBarPos != e.NewValue)
{
m_VScrollBarPos = e.NewValue;
m_AddressPos = -1;
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();
}
}
// 摘要:
// 处理垂直拉条的移动
private void m_VScrollBar_Mouse_Wheel(object obj, MouseEventArgs e)
{
return;
}
// 摘要:
// 处理鼠标移动消息
protected override void OnMouseMove(MouseEventArgs e)
{
Rectangle rtHeader = new Rectangle(0, 0, 0, 0);
Point pt = new Point(e.X, e.Y);
this.Focus();
}
// 摘要:
// 处理鼠标中间键滚动消息
protected override void OnMouseWheel(MouseEventArgs e)
{
if (m_VScrollBar.Enabled == true)
{
m_VScrollBar.Focus();
}
}
// 摘要:
// 处理鼠标按下消息
protected override void OnMouseDown(MouseEventArgs e)
{
this.Focus();
if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
{
Point pt = new Point(e.X, e.Y);
Rectangle rt = CalcEditRectangle();
Rectangle rect = new Rectangle();
Region rg;
int iHeight = 0;
int iOffset = 0;
int iWidth = 0;
SizeF sizef = CalcFontSize("00", _Font);
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
int iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (bt.Length + 1 % (int)m_HexEdit.HeadShowBit != 0)
{
iMaxDataRow += 1;
}
#region 判断是否在Address区
if (m_HexEdit.IsShowAddressColumn)
{
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
for (int ix = m_VScrollBarPos; ix < iMaxDataRow; ix++)
{
rect.X = rt.X;
rect.Y = iHeight;
rect.Width = m_HexEdit.AddressWidth;
rect.Height = _Font.Height;
rg = new Region(rect);
if (rg.IsVisible(pt))
{
m_AddressPos = ix;
if (m_AddressPos >= iMaxDataRow)
{
m_AddressPos = -1;
}
if (m_AddressPos != -1)
{
int iSTotalHeight = (ix + 1 - m_VScrollBarPos) * _Font.Height;
if (m_HexEdit.IsShowHeadColumn)
{
iSTotalHeight += m_HexEdit.HeadHeight;
}
if (iSTotalHeight > rt.Height)
{
m_VScrollBarPos++;
m_AddressPos--;
m_VScrollBar.Value = m_VScrollBarPos;
}
}
this.Invalidate();
return;
}
else
{
m_AddressPos = -1;
this.Invalidate();
}
iHeight += _Font.Height;
if (iHeight + _Font.Height > rt.Height)
{
break;
}
}
}
#endregion
#region 判断是否在Data区
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
iOffset = rt.X;
if (m_HexEdit.IsShowAddressColumn)
{
iOffset += m_HexEdit.AddressWidth;
}
rect.X = iOffset;
rect.Y = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
rect.Y += m_HexEdit.HeadHeight;
}
rect.Width = (int)m_HexEdit.HeadShowBit * (int)sizef.Width;
if ((iMaxDataRow - m_VScrollBarPos) * _Font.Height > rt.Height - rect.Y)
{
rect.Height = rt.Height - rect.Y;
}
else
{
rect.Height = (iMaxDataRow - m_VScrollBarPos) * _Font.Height;
}
rg = new Region(rect);
if (rg.IsVisible(pt))
{
//如果没有创建Caret,则创建
OnCreateCaret();
for (int ix = m_VScrollBarPos; ix < iMaxDataRow; ix++)
{
iWidth = iOffset;
for (int iy = 0; iy < (int)m_HexEdit.HeadShowBit; iy++)
{
rect.X = iWidth;
rect.Y = iHeight;
rect.Width = (int)sizef.Width / 2;
rect.Height = _Font.Height;
rg = new Region(rect);
if (rg.IsVisible(pt))
{
SetCaretPos(rect.X, rect.Y);
ShowCaret(this.Handle);
m_IsHideCaret = false;
ShowRightMouseMeun(e, pt);
m_HexMousePos.iPos = iy + ix * (int)m_HexEdit.HeadShowBit;
m_HexMousePos.iArea = 1;
m_HexMousePos.bLeftPos = true;
m_HexMousePos.bRightPos = false;
return;
}
rect.X += (int)sizef.Width / 2;
rect.Width = (int)sizef.Width - (int)sizef.Width / 2;
rg = new Region(rect);
if (rg.IsVisible(pt))
{
SetCaretPos(rect.X, rect.Y);
ShowCaret(this.Handle);
m_IsHideCaret = false;
ShowRightMouseMeun(e, pt);
m_HexMousePos.iPos = iy + ix * (int)m_HexEdit.HeadShowBit;
m_HexMousePos.iArea = 1;
m_HexMousePos.bLeftPos = false;
m_HexMousePos.bRightPos = true;
return;
}
iWidth += (int)sizef.Width;
if (iy + ix * (int)m_HexEdit.HeadShowBit >= bt.Length)
{
break;
}
}
iHeight += _Font.Height;
if (iHeight + _Font.Height >= rt.Height)
{
OnHideCaret();
break;
}
}
}
else
{
OnHideCaret();
}
#endregion
}
}
// 摘要:
// 处理鼠标按键弹起消息
protected override void OnMouseUp(MouseEventArgs e)
{
this.Focus();
}
// 摘要:
// 响应弹出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;
}
#endregion
#region 菜单函数
// 摘要:
// 插入一个string
private void MenuItem0_Click(object obj, EventArgs e)
{
if (m_HexMousePos.iPos != -1)
{
int iRow = 0;
int iColumn = 0;
Form f1 = new Form();
SizeF sizef = CalcFontSize("00", _Font);
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);
GetRowAndColumn(ref iRow, ref iColumn);
f1.Location = new System.Drawing.Point(iColumn * (int)sizef.Width, iRow * _Font.Height);
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 (Int32.Parse(strLength) == strContext.Length)
{
byte[] bt = ConvertStringToByte(strContext, m_HexEdit.DataType);
byte[] bSource = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
byte[] bDestination = new byte[bSource.Length + bt.Length];
if (m_HexMousePos.iPos > bSource.Length)
{
Array.Copy(bSource, 0, bDestination, 0, bSource.Length);
Array.Copy(bt, 0, bDestination, bSource.Length, bt.Length);
}
else
{
Array.Copy(bSource, 0, bDestination, 0, m_HexMousePos.iPos);
Array.Copy(bt, 0, bDestination, m_HexMousePos.iPos, bt.Length);
Array.Copy(bSource, m_HexMousePos.iPos,
bDestination, m_HexMousePos.iPos + bt.Length,
bSource.Length - m_HexMousePos.iPos);
}
m_HexEditData = ConvertByteToStirng(bDestination, m_HexEdit.DataType);
this.Invalidate();
}
else
{
MessageBox.Show("要插入的数据长度与实际数据的数据内容的长度不相等!");
}
}
CreateNewCaret();
}
}
// 摘要:
// 从剪贴板上复制
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[] bt = ConvertStringToByte(strData, m_HexEdit.DataType);
byte[] bSource = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
byte[] bDestination = new byte[bSource.Length + bt.Length];
if (m_HexMousePos.iPos > bSource.Length)
{
Array.Copy(bSource, 0, bDestination, 0, bSource.Length);
Array.Copy(bt, 0, bDestination, bSource.Length, bt.Length);
}
else
{
Array.Copy(bSource, 0, bDestination, 0, m_HexMousePos.iPos);
Array.Copy(bt, 0, bDestination, m_HexMousePos.iPos, bt.Length);
Array.Copy(bSource, m_HexMousePos.iPos,
bDestination, m_HexMousePos.iPos + bt.Length,
bSource.Length - m_HexMousePos.iPos);
}
m_HexEditData = ConvertByteToStirng(bDestination, m_HexEdit.DataType);
this.Invalidate();
}
}
// 摘要:
// 从文件中载入数据
private void MenuItem2_Click(object obj, EventArgs e)
{
if (m_HexMousePos.iPos == -1)
{
return;
}
if (m_HexMousePos.iArea == 1)
{
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[] bt1 = ReadHexDataFromFile(strFilePath);
string strData = ConvertByteToStirng(bt1, UIControl.HexEdit.EncodingType.ANSI);
byte[] bt = ConvertStringToByte(strData, m_HexEdit.DataType);
byte[] bSource = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
byte[] bDestination = new byte[bSource.Length + bt.Length];
if (m_HexMousePos.iPos > bSource.Length)
{
Array.Copy(bSource, 0, bDestination, 0, bSource.Length);
Array.Copy(bt, 0, bDestination, bSource.Length, bt.Length);
}
else
{
Array.Copy(bSource, 0, bDestination, 0, m_HexMousePos.iPos);
Array.Copy(bt, 0, bDestination, m_HexMousePos.iPos, bt.Length);
Array.Copy(bSource, m_HexMousePos.iPos,
bDestination, m_HexMousePos.iPos + bt.Length,
bSource.Length - m_HexMousePos.iPos);
}
m_HexEditData = ConvertByteToStirng(bDestination, m_HexEdit.DataType);
this.Invalidate();
}
CreateNewCaret();
}
}
// 摘要:
// 将数据保存至文件
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, m_HexEdit.DataType);
WriteHexDataToFile(sfd.FileName, bt);
}
CreateNewCaret();
}
// 摘要:
// 清空数据
private void MenuItem4_Click(object obj, EventArgs e)
{
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
for (int ix = 0; ix < bt.Length; ix++)
{
bt[ix] = 0;
}
m_HexEditData = ConvertByteToStirng(bt, m_HexEdit.DataType);
this.Invalidate();
}
#endregion
#region 私有函数
// 摘要:
// 获取窗体可操作区域位置
private Rectangle CalcEditRectangle()
{
Rectangle rt = new Rectangle();
rt.X = (int)fOutLineWidth / 2;
rt.Y = (int)fOutLineWidth / 2;
rt.Width = this.Width - (int)fOutLineWidth;
rt.Height = this.Height - (int)fOutLineWidth; ;
return rt;
}
// 摘要:
// 在指定Font下获取字符串的Size
private SizeF CalcFontSize(string strText, Font font)
{
Graphics g = this.CreateGraphics();
SizeF sizeF = g.MeasureString(strText, font);
g.Dispose();
return sizeF;
}
// 摘要:
// 显示垂直滚动条
private void ShowVScrollBar()
{
if (!m_VScrollBar.Enabled)
{
m_VScrollBar.Enabled = true;
m_VScrollBar.Minimum = 0;
}
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
int iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if ((bt.Length + 1) % (int)m_HexEdit.HeadShowBit == 1)
{
iMaxDataRow += 1;
}
m_VScrollBar.Maximum = iMaxDataRow + 8;
//m_VScrollBar.Show();
}
// 摘要:
// 隐藏垂直滚动条
private void HideVScrollBar()
{
Rectangle rt = CalcEditRectangle();
m_VScrollBar.Location = new Point(rt.X + rt.Width - m_VScrollBarWidth, rt.Top);
m_VScrollBar.Size = new Size(m_VScrollBarWidth, rt.Height);
m_VScrollBar.Enabled = false;
m_VScrollBar.Visible = true;
m_VScrollBarPos = 0;
}
// 摘要:
// 判断传入的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, UIControl.HexEdit.EncodingType dt)
{
if (dt == UIControl.HexEdit.EncodingType.ANSI)
{
return Encoding.GetEncoding("GB2312").GetBytes(character.ToString());
}
else if (dt == UIControl.HexEdit.EncodingType.Unicond)
{
return Encoding.GetEncoding("Unicode").GetBytes(character.ToString());
}
else
{
return null;
}
}
// 摘要:
// 将是string字符串转换成byte数组
private byte[] ConvertStringToByte(string strData, UIControl.HexEdit.EncodingType dt)
{
if (dt == UIControl.HexEdit.EncodingType.ANSI)
{
char[] cData = strData.ToCharArray();
int iLength = 0;
for (int ix = 0; ix < cData.Length; ix++)
{
if (IsChineseChar(cData[ix]))
{
iLength += 2;
}
else
{
iLength += 1;
}
}
byte[] bData = new byte[iLength];
for (int ix = 0, iy = 0; ix < cData.Length; ix++)
{
if (IsChineseChar(cData[ix]))
{
bData[iy] = (byte)((cData[ix] >> 8) & 0xFF);
iy++;
bData[iy] = (byte)cData[ix];
}
else
{
bData[iy] = Convert.ToByte(cData[ix]);
}
iy++;
}
return bData;
}
else if (dt == UIControl.HexEdit.EncodingType.Unicond)
{
return Encoding.GetEncoding("Unicode").GetBytes(strData);
}
else
{
return null;
}
}
// 摘要:
// 将是byte数组转换成string字符串
private string ConvertByteToStirng(byte[] bData, UIControl.HexEdit.EncodingType dt)
{
if (dt == UIControl.HexEdit.EncodingType.ANSI)
{
char[] cData = new char[bData.Length];
Array.Copy(bData, cData, bData.Length);
return new string(cData);
}
else if (dt == UIControl.HexEdit.EncodingType.Unicond)
{
return Encoding.GetEncoding("Unicode").GetString(bData);
}
else
{
return null;
}
}
// 摘要:
// 将一个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 ('a' <= b && b < 'f')
{
return (byte)(b - 'a' + 10);
}
else
{
return 0;
}
}
// 摘要:
// Caret向左移动
private void OnVK_Left()
{
if (m_HexMousePos.iPos != -1 &&
m_HexMousePos.iArea != -1)
{
//表明在Data区
if (m_HexMousePos.iArea == 1)
{
int iRow = m_HexMousePos.iPos / (int)m_HexEdit.HeadShowBit;
int iColumn = 0;
int iOffset = 0;
Rectangle rt = CalcEditRectangle();
Point pt = new Point();
SizeF sizef = CalcFontSize("00", _Font);
int iHeight = 0;
this.Focus();
if (m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit != 0)
{
iColumn = m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit;
}
else
{
iColumn = 0;
}
iOffset = rt.X;
if (m_HexEdit.IsShowAddressColumn)
{
iOffset += m_HexEdit.AddressWidth;
}
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
//表示在每行的起始位置
if (iColumn == 0)
{
//表明在第一个字节的右部
if (m_HexMousePos.bRightPos)
{
pt.X = iOffset;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
return;
}
//表明在第一个字节的左部
if (m_HexMousePos.bLeftPos)
{
if (iRow > 0)
{
iRow -= 1;
if (iRow < m_VScrollBarPos)
{
m_VScrollBarPos--;
m_VScrollBar.Value = m_VScrollBarPos;
this.Invalidate();
}
pt.X = iOffset + (int)m_HexEdit.HeadShowBit * (int)sizef.Width - (int)sizef.Width / 2;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos = (iRow + 1) * (int)m_HexEdit.HeadShowBit - 1;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
}
}
}
//表示不在每行的起始位置
else
{
//表明在字节的右部
if (m_HexMousePos.bRightPos)
{
pt.X = iOffset + iColumn * (int)sizef.Width;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
return;
}
//表明在字节的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = iOffset + (iColumn - 1) * (int)sizef.Width + (int)sizef.Width - (int)sizef.Width / 2;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos -= 1;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
return;
}
}
}
}
}
// 摘要:
// Caret向上移动
private void OnVK_Up()
{
if (m_AddressPos != -1)
{
if (m_AddressPos - m_VScrollBarPos == 0)
{
if (m_VScrollBarPos > 0)
{
m_VScrollBarPos--;
m_VScrollBar.Value = m_VScrollBarPos;
}
}
if (m_AddressPos - m_VScrollBarPos > 0)
{
m_AddressPos--;
}
OnHideCaret();
this.Invalidate();
}
else if (m_HexMousePos.iPos != -1 &&
m_HexMousePos.iArea != -1)
{
//表明在Data区
if (m_HexMousePos.iArea == 1)
{
int iRow = m_HexMousePos.iPos / (int)m_HexEdit.HeadShowBit;
int iColumn = 0;
int iOffset = 0;
Rectangle rt = CalcEditRectangle();
Point pt = new Point();
SizeF sizef = CalcFontSize("00", _Font);
int iHeight = 0;
int iMaxDataRow = 0;
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
this.Focus();
iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if ((bt.Length + 1) % (int)m_HexEdit.HeadShowBit == 1)
{
iMaxDataRow += 1;
}
if (m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit != 0)
{
iColumn = m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit;
}
else
{
iColumn = 0;
}
iOffset = rt.X;
if (m_HexEdit.IsShowAddressColumn)
{
iOffset += m_HexEdit.AddressWidth;
}
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
if (iRow >= m_VScrollBarPos)
{
if (iRow > 0 && iRow == m_VScrollBarPos)
{
m_VScrollBarPos--;
m_VScrollBar.Value = m_VScrollBarPos;
this.Invalidate();
}
if (iRow == 0)
{
return;
}
iRow--;
//表明在第一个字节的右部
if (m_HexMousePos.bRightPos)
{
pt.X = iOffset + iColumn * (int)sizef.Width + (int)sizef.Width / 2;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos -= (int)m_HexEdit.HeadShowBit;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
return;
}
//表明在第一个字节的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = iOffset + iColumn * (int)sizef.Width;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos -= (int)m_HexEdit.HeadShowBit;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
return;
}
}
}
}
}
// 摘要:
// Caret向右移动
private void OnVK_Right()
{
if (m_HexMousePos.iPos != -1 &&
m_HexMousePos.iArea != -1)
{
//表明在Data区
if (m_HexMousePos.iArea == 1)
{
int iRow = m_HexMousePos.iPos / (int)m_HexEdit.HeadShowBit;
int iColumn = 0;
int iOffset = 0;
Rectangle rt = CalcEditRectangle();
Point pt = new Point();
SizeF sizef = CalcFontSize("00", _Font);
int iHeight = 0;
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
this.Focus();
int iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (bt.Length % (int)m_HexEdit.HeadShowBit == 1)
{
iMaxDataRow += 1;
}
int iMaxShowRow = 0;
for (int ix = 0; ix < 0xFFFF; ix++)
{
iHeight = (ix + 1) * _Font.Height;
if (iHeight + _Font.Height > rt.Height)
{
iMaxShowRow = ix;
break;
}
}
if (m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit != 0)
{
iColumn = m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit;
}
else
{
iColumn = 0;
}
iOffset = rt.X;
if (m_HexEdit.IsShowAddressColumn)
{
iOffset += m_HexEdit.AddressWidth;
}
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
//表明在最后一个字节
if (iColumn == 0x0F)
{
//表明在字节的右部
if (m_HexMousePos.bRightPos)
{
if (iRow < iMaxDataRow)
{
iRow++;
if (iRow - m_VScrollBarPos > iMaxShowRow - 1)
{
m_VScrollBarPos++;
m_VScrollBar.Value = m_VScrollBarPos;
this.Invalidate();
}
pt.X = iOffset;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos += 1;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
return;
}
}
//表明在字节的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = iOffset + iColumn * (int)sizef.Width + (int)sizef.Width / 2;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
return;
}
}
else
{
//表明在字节的右部
if (m_HexMousePos.bRightPos)
{
if (iRow * (int)m_HexEdit.HeadShowBit + iColumn + 1 > bt.Length)
{
return;
}
pt.X = iOffset + (iColumn + 1) * (int)sizef.Width;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos += 1;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
return;
}
//表明在字节的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = iOffset + iColumn * (int)sizef.Width + (int)sizef.Width / 2;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
return;
}
}
}
}
}
// 摘要:
// Caret向下移动
private void OnVK_Down()
{
if (m_AddressPos != -1)
{
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
int iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if (bt.Length % (int)m_HexEdit.HeadShowBit != 0)
{
iMaxDataRow += 1;
}
int iShowMaxRow = 0;
int iHeight = 0;
Rectangle rt = CalcEditRectangle();
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
for (int ix = 0; ix < 0xFFFF; ix++)
{
iHeight = (ix + 1) * _Font.Height;
if (iHeight + _Font.Height > rt.Height)
{
iShowMaxRow = ix;
break;
}
}
if ((m_AddressPos - m_VScrollBarPos) == iShowMaxRow - 1)
{
if (m_VScrollBarPos < iMaxDataRow - 8)
{
m_VScrollBarPos++;
m_VScrollBar.Value = m_VScrollBarPos;
}
}
if ((m_AddressPos - m_VScrollBarPos) < iShowMaxRow - 1 &&
m_AddressPos < iMaxDataRow - 1)
{
m_AddressPos++;
}
OnHideCaret();
this.Invalidate();
}
else if (m_HexMousePos.iPos != -1 &&
m_HexMousePos.iArea != -1)
{
//表明在Data区
if (m_HexMousePos.iArea == 1)
{
int iRow = m_HexMousePos.iPos / (int)m_HexEdit.HeadShowBit;
int iColumn = 0;
int iOffset = 0;
Rectangle rt = CalcEditRectangle();
Point pt = new Point();
SizeF sizef = CalcFontSize("00", _Font);
int iHeight = 0;
int iMaxShowRow = 0;
int iMaxDataRow = 0;
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
this.Focus();
iMaxDataRow = bt.Length / (int)m_HexEdit.HeadShowBit;
if ((bt.Length + 1) % (int)m_HexEdit.HeadShowBit == 1)
{
iMaxDataRow += 1;
}
if (m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit != 0)
{
iColumn = m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit;
}
else
{
iColumn = 0;
}
iOffset = rt.X;
if (m_HexEdit.IsShowAddressColumn)
{
iOffset += m_HexEdit.AddressWidth;
}
for (int ix = 0; ix < 0xFFFF; ix++)
{
iHeight = (ix + 1) * _Font.Height;
if (iHeight + _Font.Height > rt.Height)
{
iMaxShowRow = ix;
break;
}
}
iHeight = rt.Y;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
if (iRow <= iMaxDataRow)
{
if ((iRow + 1) * (int)m_HexEdit.HeadShowBit + iColumn + 1 > bt.Length + 1)
{
return;
}
if (iRow - m_VScrollBarPos == iMaxShowRow - 1 )
{
m_VScrollBarPos++;
m_VScrollBar.Value = m_VScrollBarPos;
this.Invalidate();
}
if (iRow == iMaxDataRow)
{
return;
}
iRow++;
//表明在第一个字节的右部
if (m_HexMousePos.bRightPos)
{
pt.X = iOffset + iColumn * (int)sizef.Width + (int)sizef.Width / 2;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos += (int)m_HexEdit.HeadShowBit;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
return;
}
//表明在第一个字节的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = iOffset + iColumn * (int)sizef.Width;
pt.Y = iHeight + (iRow - m_VScrollBarPos) * _Font.Height;
m_HexMousePos.iPos += (int)m_HexEdit.HeadShowBit;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
return;
}
}
}
}
}
// 摘要:
// 创建Caret
private void OnCreateCaret()
{
//如果没有创建Caret,则创建
if (!m_IsCreateCaret)
{
m_IsCreateCaret = true;
CreateCaret(this.Handle, IntPtr.Zero, (int)_Font.Size, _Font.Height);
}
}
// 摘要:
// 隐藏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;
}
// 摘要:
// 显示右键菜单
private void ShowRightMouseMeun(MouseEventArgs e, Point pt)
{
if (e.Button == MouseButtons.Right)
{
m_HexMenu.Show(this, pt);
}
}
// 摘要:
// 判断文件是否存在
private bool IsFileExist(string path)
{
if (File.Exists(path))
{
return true;
}
else
{
return false;
}
}
// 摘要:
// 从文件中读取十六进制数据流
private byte[] ReadHexDataFromFile(string path)
{
if (!IsFileExist(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 bool WriteHexDataToFile(string path, byte[] bt)
{
if (IsFileExist(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 GetRowAndColumn(ref int iRow, ref int iColumn)
{
if (m_HexMousePos.iPos != -1)
{
if (m_HexMousePos.iArea == 1)
{
iRow = m_HexMousePos.iPos / (int)m_HexEdit.HeadShowBit;
iColumn = m_HexMousePos.iPos % (int)m_HexEdit.HeadShowBit;
return;
}
}
iRow = -1;
iColumn = -1;
}
// 摘要:
// 重新生成Caret
private void CreateNewCaret()
{
int irow = 0;
int iColumn = 0;
Rectangle rt = CalcEditRectangle();
SizeF sizef = CalcFontSize("00", _Font);
int iHeight = 0;
int iWidth = 0;
if (m_IsCreateCaret)
{
DestroyCaret();
m_IsCreateCaret = false;
}
if (!m_IsCreateCaret)
{
GetRowAndColumn(ref irow, ref iColumn);
if (irow != -1 && iColumn != -1)
{
OnCreateCaret();
m_IsCreateCaret = true;
iHeight = rt.Y + (irow - m_VScrollBarPos) * _Font.Height;
if (m_HexEdit.IsShowHeadColumn)
{
iHeight += m_HexEdit.HeadHeight;
}
iWidth = rt.X + iColumn * (int)sizef.Width;
if (m_HexEdit.IsShowAddressColumn)
{
iWidth += m_HexEdit.AddressWidth;
}
if (m_HexMousePos.bRightPos)
{
iWidth += (int)sizef.Width / 2;
}
SetCaretPos(iWidth, iHeight);
ShowCaret(this.Handle);
byte[] bt = ConvertStringToByte(m_HexEditData, m_HexEdit.DataType);
m_VScrollBar.Maximum = bt.Length / (int)m_HexEdit.HeadShowBit + 8;
}
}
}
#endregion
#region 私有变量
// 摘要:
// 垂直滚动条
private VScrollBar m_VScrollBar;
// 摘要:
// 垂直滚动条的位置
private int m_VScrollBarPos;
// 摘要:
// 垂直滚动条宽度
private int m_VScrollBarWidth;
// 摘要:
// HexEdit控件
private HexEdit m_HexEdit;
// 摘要:
// HexEdit控件中鼠标选择的数据位置
private POS m_HexMousePos;
private struct POS
{
public int iPos;
public int iArea;
public bool bLeftPos;
public bool bRightPos;
}
// 摘要:
// HexEdit控件中鼠标单击Address栏的位置
private int m_AddressPos;
// 摘要:
// 是否创建了Caret
private bool m_IsCreateCaret;
// 摘要:
// 是否隐藏了Caret
private bool m_IsHideCaret;
// 摘要:
// 菜单
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 动态加载函数
[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
}
}
3. 在WPF主界面XAML中按照以下方式编写
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WF="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:Hx="clr-namespace:Sense.Test.UIControl;assembly=TextEditControl"
x:Name="Window"
Title="开发测试工具"
Width="900" Height="600" Background="White" WindowState="Maximized">
<Grid>
<WF:WindowsFormsHost Margin="5, 10, 5, 5">
<Hx:TextEditControl HexEditData="12345678123456781234234567812345678123423456781234567812342345678123456781234234567812345678123423456781234567812342345678123456781234234567812345678123423456781234567812342345678123456781234234567812345678123423456781234567812342345678123456781234"/>
</WF:WindowsFormsHost>
</Grid>
</Window>
4. 编译完成