C# HexEdit
新建HexEditProperties.cs,將以下程式碼拷貝至該檔案
using System.Drawing;
namespace TestHexEdit
{
public class HexEditProperties
{
/// <summary>
/// 預設建構函式
/// </summary>
public HexEditProperties()
{
//預設顯示頭部
IsSupportDisplayHexHead = true;
HexHeadHeight = 25;
HexHeadBackgroundTopColor = Color.FromArgb(236, 244, 252);
HexHeadBackgroundBottomColor = Color.FromArgb(220, 230, 245);
HexHeadBackgroundBottomFLineColor = Color.FromArgb(228, 239, 251);
HexHeadBackgroundBottomSLineColor = Color.FromArgb(205, 218, 234);
HexHeadBackgroundBottomTLineColor = Color.FromArgb(160, 175, 195);
HexHeadFontColor = Color.Black;
HexHeadStaffColor = Color.Black;
//設定背景色
HexBackgroundColor = Color.White;
//設定背景字型
HexBackgroundFont = new Font("宋體", 10);
//設定字型顯示型別
HexDataType = EncodingType.ANSI;
HexDataFontColor = Color.Black;
//設定外部線條
HexOutLineWidth = 2;
HexOutLineColor = Color.Black;
//預設顯示位址列
IsSupportHexAddress = true;
HexAddressWidth = 100;
HexAddressShowBit = AddressBit.Bit8;
HexAddressBackgroundColor = Color.White;
HexAddressFontColor = Color.Black;
//設定選擇框的顏色
HexSelectBorderFColor = Color.FromArgb(213, 231, 252);
HexSelectBorderSColor = Color.FromArgb(193, 220, 252);
HexSelectBorderOLColor = Color.FromArgb(235, 244, 253);
//設定選單屬性
IsSupportDisplayMenu = true;
}
#region 控制元件頭部屬性
/// <summary>
/// 用於判定是否顯示HexEdit的頭部
/// </summary>
private bool _IsSupportDisplayHexHead;
public bool IsSupportDisplayHexHead
{
get
{
return _IsSupportDisplayHexHead;
}
set
{
_IsSupportDisplayHexHead = value;
}
}
/// <summary>
/// HexEdit的Head的高度
/// </summary>
private int _HexHeadHeight;
public int HexHeadHeight
{
get
{
return _HexHeadHeight;
}
set
{
_HexHeadHeight = value;
}
}
/// <summary>
/// HexEdit的Background的上半部分顏色
/// </summary>
private Color _HexHeadBackgroundTopColor;
public Color HexHeadBackgroundTopColor
{
get
{
return _HexHeadBackgroundTopColor;
}
set
{
_HexHeadBackgroundTopColor = value;
}
}
/// <summary>
/// HexEdit的Background的下半部分顏色
/// </summary>
private Color _HexHeadBackgroundBottomColor;
public Color HexHeadBackgroundBottomColor
{
get
{
return _HexHeadBackgroundBottomColor;
}
set
{
_HexHeadBackgroundBottomColor = value;
}
}
/// <summary>
/// HexEdit的Background的下半部分第一個Line的顏色
/// </summary>
private Color _HexHeadBackgroundBottomFLineColor;
public Color HexHeadBackgroundBottomFLineColor
{
get
{
return _HexHeadBackgroundBottomFLineColor;
}
set
{
_HexHeadBackgroundBottomFLineColor = value;
}
}
/// <summary>
/// HexEdit的Background的下半部分第二個Line的顏色
/// </summary>
private Color _HexHeadBackgroundBottomSLineColor;
public Color HexHeadBackgroundBottomSLineColor
{
get
{
return _HexHeadBackgroundBottomSLineColor;
}
set
{
_HexHeadBackgroundBottomSLineColor = value;
}
}
/// <summary>
/// HexEdit的Background的下半部分第三個Line的顏色
/// </summary>
private Color _HexHeadBackgroundBottomTLineColor;
public Color HexHeadBackgroundBottomTLineColor
{
get
{
return _HexHeadBackgroundBottomTLineColor;
}
set
{
_HexHeadBackgroundBottomTLineColor = value;
}
}
/// <summary>
/// HexEdit的標尺字型的顏色
/// </summary>
private Color _HexHeadFontColor;
public Color HexHeadFontColor
{
get
{
return _HexHeadFontColor;
}
set
{
_HexHeadFontColor = value;
}
}
/// <summary>
/// HexEdit的標尺的顏色
/// </summary>
private Color _HexHeadStaffColor;
public Color HexHeadStaffColor
{
get
{
return _HexHeadStaffColor;
}
set
{
_HexHeadStaffColor = value;
}
}
#endregion
#region 控制元件外部線條屬性
/// <summary>
/// HexEdit的外部線條的顏色
/// </summary>
private Color _HexOutLineColor;
public Color HexOutLineColor
{
get
{
return _HexOutLineColor;
}
set
{
_HexOutLineColor = value;
}
}
/// <summary>
/// HexEdit的外部線條的寬度
/// </summary>
private int _HexOutLineWidth;
public int HexOutLineWidth
{
get
{
return _HexOutLineWidth;
}
set
{
_HexOutLineWidth = value;
}
}
#endregion
#region 背景色
/// <summary>
/// HexEdit的背景色的顏色
/// </summary>
private Color _HexBackgroundColor;
public Color HexBackgroundColor
{
get
{
return _HexBackgroundColor;
}
set
{
_HexBackgroundColor = value;
}
}
#endregion
#region 控制元件字型屬性
private Font _HexBackgroundFont;
public Font HexBackgroundFont
{
get
{
return _HexBackgroundFont;
}
set
{
_HexBackgroundFont = value;
}
}
#endregion
#region 控制元件資料屬性
/// <summary>
/// 顯示格式
/// </summary>
private EncodingType _HexDataType;
public EncodingType HexDataType
{
get
{
return _HexDataType;
}
set
{
_HexDataType = value;
}
}
public enum EncodingType
{
ANSI = 1,
Unicond
}
/// <summary>
/// 資料字型顏色
/// </summary>
private Color _HexDataFontColor;
public Color HexDataFontColor
{
get
{
return _HexDataFontColor;
}
set
{
_HexDataFontColor = value;
}
}
#endregion
#region 控制元件位址列屬性
/// <summary>
/// 顯示控制元件位址列屬性
/// </summary>
private bool _IsSupportHexAddress;
public bool IsSupportHexAddress
{
get
{
return _IsSupportHexAddress;
}
set
{
_IsSupportHexAddress = value;
}
}
/// <summary>
/// 顯示控制元件位址列的背景顏色
/// </summary>
private Color _HexAddressBackgroundColor;
public Color HexAddressBackgroundColor
{
get
{
return _HexAddressBackgroundColor;
}
set
{
_HexAddressBackgroundColor = value;
}
}
/// <summary>
/// 控制元件位址列的寬度
/// </summary>
private int _HexAddressWidth;
public int HexAddressWidth
{
get
{
return _HexAddressWidth;
}
set
{
_HexAddressWidth = value;
}
}
/// <summary>
/// 控制元件位址列地址的顯示位數
/// </summary>
private AddressBit _HexAddressShowBit;
public AddressBit HexAddressShowBit
{
get
{
return _HexAddressShowBit;
}
set
{
_HexAddressShowBit = value;
}
}
public enum AddressBit
{
Bit4 = 1,
Bit8
}
/// <summary>
/// 控制元件位址列地址字型的顯示顏色
/// </summary>
private Color _HexAddressFontColor;
public Color HexAddressFontColor
{
get
{
return _HexAddressFontColor;
}
set
{
_HexAddressFontColor = value;
}
}
#endregion
#region 控制元件單行選擇背景框顏色
/// <summary>
/// 選擇框的上半部分顏色
/// </summary>
private Color _HexSelectBorderFColor;
public Color HexSelectBorderFColor
{
get
{
return _HexSelectBorderFColor;
}
set
{
_HexSelectBorderFColor = value;
}
}
/// <summary>
/// 選擇框的下半部分顏色
/// </summary>
private Color _HexSelectBorderSColor;
public Color HexSelectBorderSColor
{
get
{
return _HexSelectBorderSColor;
}
set
{
_HexSelectBorderSColor = value;
}
}
/// <summary>
/// 選擇框的外部線條顏色
/// </summary>
private Color _HexSelectBorderOLColor;
public Color HexSelectBorderOLColor
{
get
{
return _HexSelectBorderOLColor;
}
set
{
_HexSelectBorderOLColor = value;
}
}
#endregion
#region 右鍵選單屬性
/// <summary>
/// 用於判定是否顯示右鍵選單
/// </summary>
private bool _IsSupportDisplayMenu;
public bool IsSupportDisplayMenu
{
get
{
return _IsSupportDisplayMenu;
}
set
{
_IsSupportDisplayMenu = value;
}
}
#endregion
}
}
新建HexEdit.cs檔案,將以下程式碼拷貝至該檔案
using System;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.IO;
namespace TestHexEdit
{
public class HexEdit : Control
{
#region 私有變數
//控制元件屬性
private HexEditProperties hep;
//當前實際顯示的起始行數
private int i_start_display = 0;
//每行顯示的資料個數
private int i_row_display = 16;
//每行中字元間的間隔
private int i_row_staff = 10;
//每列中字元間的間隔
private int i_Column_staff = 5;
// 摘要:
// HexEdit控制元件顯示的資料
private string m_HexEditData = null;
// 摘要:
// HexEdit控制元件中滑鼠選擇的資料位置
private POS m_HexMousePos;
private struct POS
{
public int iPos;
public int iArea;
public bool bLeftPos;
public bool bRightPos;
}
//下拉控制元件的寬度
private int i_Scroll_Width = 15;
//當前選中的行
private int i_Select_Row = -1;
// 摘要:
// 垂直滾動條
private VScrollBar m_VScrollBar;
// 摘要:
// 是否建立了Caret
private bool m_IsCreateCaret = false;
// 摘要:
// 是否隱藏了Caret
private bool m_IsHideCaret = false;
// 摘要:
// 選單
private ContextMenu m_HexMenu;
private MenuItem m_HexMenuItem0;
private MenuItem m_HexMenuItem1;
private MenuItem m_HexMenuItem2;
private MenuItem m_HexMenuItem3;
private MenuItem m_HexMenuItem4;
#endregion
#region 預設建構函式
/// <summary>
/// 預設建構函式
/// </summary>
public HexEdit()
{
//設定窗體Style
this.SetStyle(ControlStyles.UserPaint, true); //支援使用者重繪窗體
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); //在記憶體中先繪製介面
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //雙緩衝,防止繪製時抖動
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.UpdateStyles();
//建立控制元件屬性
hep = new HexEditProperties();
//設定位置屬性
m_HexMousePos = new POS();
m_HexMousePos.iPos = -1;
m_HexMousePos.iArea = -1;
m_HexMousePos.bLeftPos = false;
m_HexMousePos.bRightPos = false;
//初始化垂直滾動條
m_VScrollBar = new System.Windows.Forms.VScrollBar();
m_VScrollBar.Visible = false;
m_VScrollBar.Enabled = false;
m_VScrollBar.Width = i_Scroll_Width;
m_VScrollBar.Minimum = 0;
m_VScrollBar.Maximum = 0;
m_VScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(m_VScrollBar_Scroll);
this.Controls.Add(m_VScrollBar);
//初始化選單
m_HexMenu = new ContextMenu();
m_HexMenuItem0 = new MenuItem();
m_HexMenuItem0.Text = "Insert a string...";
m_HexMenuItem0.Name = "string";
m_HexMenuItem0.Click += new System.EventHandler(MenuItem0_Click);
m_HexMenuItem1 = new MenuItem();
m_HexMenuItem1.Text = "Paste a string from clipboard";
m_HexMenuItem1.Name = "paste";
m_HexMenuItem1.Click += new System.EventHandler(MenuItem1_Click);
m_HexMenuItem2 = new MenuItem();
m_HexMenuItem2.Text = "Load from file...";
m_HexMenuItem2.Name = "Load";
m_HexMenuItem2.Click += new System.EventHandler(MenuItem2_Click);
m_HexMenuItem3 = new MenuItem();
m_HexMenuItem3.Text = "Save to file...";
m_HexMenuItem3.Name = "save";
m_HexMenuItem3.Click += new System.EventHandler(MenuItem3_Click);
m_HexMenuItem4 = new MenuItem();
m_HexMenuItem4.Text = "Clear this memory block";
m_HexMenuItem4.Name = "clear";
m_HexMenuItem4.Click += new System.EventHandler(MenuItem4_Click);
m_HexMenu.MenuItems.Add(m_HexMenuItem0);
m_HexMenu.MenuItems.Add(m_HexMenuItem1);
m_HexMenu.MenuItems.Add("-");
m_HexMenu.MenuItems.Add(m_HexMenuItem2);
m_HexMenu.MenuItems.Add(m_HexMenuItem3);
m_HexMenu.MenuItems.Add("-");
m_HexMenu.MenuItems.Add(m_HexMenuItem4);
}
/// <summary>
/// 預設解構函式
/// </summary>
~HexEdit()
{
if (m_IsCreateCaret)
{
DestroyCaret();
}
}
#endregion
#region 動態修改控制元件屬性
/// <summary>
/// 獲取或者設定控制元件屬性
/// </summary>
public HexEditProperties HEProperties
{
get
{
return hep;
}
set
{
hep = value;
}
}
#endregion
#region 控制元件繪畫函式
/// <summary>
/// 過載繪製函式
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
//設定窗體的背景色
this.BackColor = hep.HexBackgroundColor;
this.Focus();
//判定是否需要繪製頭部
if (hep.IsSupportDisplayHexHead)
{
OnDrawHexEditHead(e);
}
//判定是否需要繪製位址列
if (hep.IsSupportHexAddress)
{
OnDrawHexEditAddress(e);
}
//繪製資料區域
OnDrawHexEditData(e);
//繪製選擇框
OnDrawHexEditAddressSelectEdit(e);
//繪製外部線條
OnDrawEditOutLine(e);
}
/// <summary>
/// 繪製外部線條
/// </summary>
/// <param name="e"></param>
private void OnDrawEditOutLine(PaintEventArgs e)
{
Point[] pt = { new Point(0, 0),
new Point(this.Width, 0),
new Point(this.Width, this.Height),
new Point(0, this.Height),
new Point(0, 0) };
Pen pen = new Pen(hep.HexOutLineColor, hep.HexOutLineWidth);
e.Graphics.DrawLines(pen, pt);
}
/// <summary>
/// 繪製HexEdit的頭部
/// </summary>
/// <param name="e"></param>
private void OnDrawHexEditHead(PaintEventArgs e)
{
//判定起始點
Point pt = new Point(hep.HexOutLineWidth / 2, hep.HexOutLineWidth / 2);
//獲得繪製實際的寬度
int width = this.Width - hep.HexOutLineWidth;
//獲得Head的寬度(每個線條佔用1的高度)
int height = hep.HexHeadHeight - 3;
//繪製Head上半部分
Brush brush_top = new SolidBrush(hep.HexHeadBackgroundTopColor);
Rectangle headrt = new Rectangle(pt.X, pt.Y, width, height / 2);
e.Graphics.FillRectangle(brush_top, headrt);
pt.Y += height / 2;
//繪製Head下半部分
Brush brush_bottom = new SolidBrush(hep.HexHeadBackgroundBottomColor);
headrt = new Rectangle(pt.X, pt.Y, width, height - height / 2);
e.Graphics.FillRectangle(brush_bottom, headrt);
pt.Y += height - height / 2;
//繪製第一條線
Pen pen_f = new Pen(hep.HexHeadBackgroundBottomFLineColor);
e.Graphics.DrawLine(pen_f, pt, new Point(width, pt.Y));
pt.Y += 1;
//繪製第二條線
Pen pen_s = new Pen(hep.HexHeadBackgroundBottomSLineColor);
e.Graphics.DrawLine(pen_s, pt, new Point(width, pt.Y));
pt.Y += 1;
//繪製第三條線
Pen pen_t = new Pen(hep.HexHeadBackgroundBottomTLineColor);
e.Graphics.DrawLine(pen_t, pt, new Point(width, pt.Y));
pt.Y += 1;
//計算字型實際佔用的大小
int i_font_width = GetFontSizeFWidth();
//設定字型的起始位置
int i_offset = hep.HexOutLineWidth / 2 + i_row_staff;
if (hep.IsSupportHexAddress)
{
i_offset += hep.HexAddressWidth;
}
//繪製標尺及字型
Point pt1 = new Point();
Point pt2 = new Point();
Brush brush_staff = new SolidBrush(hep.HexHeadFontColor);
Pen pen_staff = new Pen(hep.HexHeadStaffColor);
for (int i = 0; i < i_row_display; i++)
{
//繪製資料
string strMsg = i.ToString("X2");
pt1.X = i_offset;
pt1.Y = height / 5;
e.Graphics.DrawString(strMsg, hep.HexBackgroundFont, brush_staff, pt1);
//繪製標尺
pt1.X += i_font_width / 2;
pt1.Y += hep.HexBackgroundFont.Height - 4;
pt2.X = pt1.X;
pt2.Y = pt1.Y + 2;
e.Graphics.DrawLine(pen_staff, pt1, pt2);
i_offset += i_font_width + i_row_staff;
}
}
/// <summary>
/// 繪製HexEdit的位址列
/// </summary>
/// <param name="e"></param>
private void OnDrawHexEditAddress(PaintEventArgs e)
{
//如果資料為空,則直接返回
if (m_HexEditData == null)
{
return;
}
//判定起始點
Point pt = GetAddressAreaStartPos();
//計算控制元件最大可顯示的行數
int iMaxDataRow = GetControlMaxRowShowCount();
//設定背景框
Brush bgbrush = new SolidBrush(hep.HexAddressBackgroundColor);
//設定字型
Brush fontbrush = new SolidBrush(hep.HexAddressFontColor);
//計算實際資料可顯示的行數
int i_data_row = GetDataNeedDisplayRowShowCount();
//計算字型的顯示高度
int i_font_height = GetFontSizeFHeigth();
//計算實際起始寫的位置
int i_offset = 0;
SizeF sizef_add;
if (hep.HexAddressShowBit == HexEditProperties.AddressBit.Bit4)
{
sizef_add = CalcFontSize("0000", hep.HexBackgroundFont);
}
else
{
sizef_add = CalcFontSize("00000000", hep.HexBackgroundFont);
}
if (hep.HexAddressWidth < (int)(sizef_add.Width + 1))
{
hep.HexAddressWidth = (int)(sizef_add.Width + 1);
}
i_offset = hep.HexAddressWidth - (int)(sizef_add.Width + 1);
//設定繪製區域
Rectangle art = new Rectangle();
Point pt1 = new Point();
string strMsg = null;
for (int ix = i_start_display; ix < i_start_display + iMaxDataRow; ix++)
{
if (i_data_row <= ix)
{
break;
}
art.X = pt.X;
art.Y = pt.Y + (ix - i_start_display) * (i_font_height + i_Column_staff);
art.Width = hep.HexAddressWidth;
art.Height = i_font_height + i_Column_staff;
e.Graphics.FillRectangle(bgbrush, art);
pt1.X = art.X + i_offset;
pt1.Y = art.Y + (i_font_height + i_Column_staff) / 4;
if (hep.HexAddressShowBit == HexEditProperties.AddressBit.Bit4)
{
strMsg = (ix * i_row_display).ToString("X4");
}
else
{
strMsg = (ix * i_row_display).ToString("X8");
}
e.Graphics.DrawString(strMsg, hep.HexBackgroundFont, fontbrush, pt1);
}
}
/// <summary>
/// 繪製資料區
/// </summary>
/// <param name="e"></param>
private void OnDrawHexEditData(PaintEventArgs e)
{
//如果資料為空,則直接返回
if (m_HexEditData == null)
{
return;
}
//判定起始點
Point pt = GetDataAreaStartPos();
//計算字型的高度及寬度
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
//計算控制元件最大可顯示的行數
int iMaxDataRow = GetControlMaxRowShowCount();
//設定字型
Brush fontbrush = new SolidBrush(hep.HexDataFontColor);
//計算實際資料可顯示的行數
int i_data_row = GetDataNeedDisplayRowShowCount();
//設定繪製區域
Point pt1 = new Point();
string strMsg = null;
int i_data_offset = i_start_display * i_row_display;
int iHeight = pt.Y + (i_font_height + i_Column_staff) / 4;
for (int ix = i_start_display; ix < i_start_display + iMaxDataRow; ix++)
{
if (i_data_row <= ix)
{
break;
}
pt1.X = pt.X + i_row_staff;
pt1.Y = iHeight;
for (int iy = i_data_offset; iy < i_data_offset + i_row_display; iy++)
{
if (iy >= GetDataLength())
{
break;
}
strMsg = GetDataByPos(iy).ToString("X2");
e.Graphics.DrawString(strMsg, hep.HexBackgroundFont, fontbrush, pt1);
pt1.X += i_font_width + i_row_staff;
}
i_data_offset += i_row_display;
iHeight += i_font_height + i_Column_staff;
}
}
/// <summary>
/// 繪製選擇行的背景色
/// </summary>
/// <param name="e"></param>
private void OnDrawHexEditAddressSelectEdit(PaintEventArgs e)
{
if (i_Select_Row == -1)
{
return;
}
//判定起始點
Point pt = GetAddressAreaStartPos();
//計算行高
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
Rectangle rect = new Rectangle();
rect.X = pt.X;
rect.Y = pt.Y + i_Select_Row * (i_font_height + i_Column_staff);
rect.Width = this.Width - hep.HexOutLineWidth;
rect.Height = i_font_height + i_Column_staff;
//填充區域
//LinearGradientBrush lgbrush = new LinearGradientBrush(rect, hep.HexSelectBorderFColor, hep.HexSelectBorderSColor, LinearGradientMode.Vertical);
//lgbrush.SetSigmaBellShape(0.5f);
Brush lgbrush = new SolidBrush(Color.FromArgb(150, hep.HexSelectBorderSColor));
e.Graphics.FillRectangle(lgbrush, rect);
//繪製外線
e.Graphics.DrawRectangle(new Pen(hep.HexSelectBorderOLColor, 1), rect);
}
#endregion
#region 重寫函式
// 摘要:
// 過載訊息處理函式,該函式不處理WM_ERASEBKGRND訊息
protected override void WndProc(ref Message m)
{
//0x00000014 WM_ERASEBKGRND
if (m.Msg == 0x00000014)
{
return;
}
base.WndProc(ref m);
}
// 摘要:
// 處理鍵盤輸入鍵訊息
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
{
if (keyData >= Keys.D0 && keyData <= Keys.F ||
keyData >= Keys.NumPad0 && keyData <= Keys.NumPad9)
{
byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);
byte b = 0;
byte c = 0;
this.Focus();
if (m_HexMousePos.iPos < bt.Length)
{
if (m_HexMousePos.bLeftPos)
{
c = (byte)(bt[m_HexMousePos.iPos] & 0x0F);
b = HexCharValue((byte)keyData);
}
if (m_HexMousePos.bRightPos)
{
b = (byte)((bt[m_HexMousePos.iPos] & 0xF0) >> 4);
c = HexCharValue((byte)keyData);
}
bt[m_HexMousePos.iPos] = (byte)((b << 4) | c);
m_HexEditData = ConvertByteToStirng(bt, hep.HexDataType);
this.Invalidate();
OnVK_Right();
}
return true;
}
else
{
switch (keyData)
{
case Keys.Up:
OnVK_Up();
break;
case Keys.Down:
OnVK_Down();
break;
case Keys.Left:
OnVK_Left();
break;
case Keys.Right:
OnVK_Right();
break;
}
}
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
#endregion
#region 訊息事件函式
/// <summary>
/// 響應滑鼠按下訊息
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown(MouseEventArgs e)
{
//如果資料為空,則直接返回
if (m_HexEditData == null)
{
return;
}
//只響應這兩個訊息
if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
{
//記錄滑鼠的座標
Point mouse_pt = new Point(e.X, e.Y);
#region 變數計算
//判定起始點
Point pt = GetAddressAreaStartPos();
//獲取字型的高度及寬度
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
//計算控制元件最大可顯示的行數
int iMaxDataRow = GetControlMaxRowShowCount();
//計算實際資料可顯示的行數
int i_data_row = GetDataNeedDisplayRowShowCount();
#endregion
#region 判定是否在當前行中
//判定是否在當前行中
Rectangle rect = new Rectangle();
Region rg;
int iHeight = pt.Y;
for (int ix = i_start_display; ix < i_start_display + iMaxDataRow; ix++)
{
if (i_data_row <= ix)
{
//表明沒有選中行
i_Select_Row = -1;
break;
}
rect.X = pt.X;
rect.Y = iHeight;
rect.Width = this.Width - hep.HexOutLineWidth;
rect.Height = i_font_height + i_Column_staff;
rg = new Region(rect);
if (rg.IsVisible(mouse_pt))
{
//表明選中了某一行
i_Select_Row = ix - i_start_display;
this.Invalidate();
break;
}
iHeight += i_font_height + i_Column_staff;
}
if(i_Select_Row == -1)
{
//沒有選中行
return;
}
#endregion
#region 設定顯示
//需要判定是否在Data區域
//計算Data區域的起始位置
Point pt_data;
int i_offset = 0;
if (hep.IsSupportHexAddress)
{
i_offset = hep.HexOutLineWidth / 2 + hep.HexAddressWidth;
}
else
{
i_offset = hep.HexOutLineWidth / 2;
}
pt_data = new Point(i_offset, pt.Y);
rect.X = pt_data.X;
rect.Y = pt_data.Y + i_Select_Row * (i_font_height + i_Column_staff);
rect.Width = i_row_display * (i_row_staff + i_font_width);
rect.Height = i_font_height + i_Column_staff;
rg = new Region(rect);
if (rg.IsVisible(mouse_pt))
{
//表明在Data區域
//如果沒有建立Caret,則建立
OnCreateCaret();
int i_data_offset = rect.X + i_row_staff;
int i_data_height = rect.Y;
for (int iy = 0; iy < i_row_display; iy++)
{
rect.X = i_data_offset;
rect.Y = i_data_height;
rect.Width = i_font_width / 2;
rect.Height = i_font_height + i_Column_staff;
rg = new Region(rect);
if (rg.IsVisible(mouse_pt))
{
SetCaretPos(rect.X, rect.Y);
ShowCaret(this.Handle);
m_IsHideCaret = false;
ShowRightMouseMeun(e, mouse_pt);
m_HexMousePos.iPos = (i_start_display + i_Select_Row) * i_row_display + iy;
m_HexMousePos.iArea = 1;
m_HexMousePos.bLeftPos = true;
m_HexMousePos.bRightPos = false;
break;
}
rect.X += i_font_width / 2;
//rect.Width = i_font_width - i_font_width / 2;
rect.Width = i_font_width - i_font_width / 2 + i_row_staff;
rg = new Region(rect);
if (rg.IsVisible(mouse_pt))
{
SetCaretPos(rect.X, rect.Y);
ShowCaret(this.Handle);
m_IsHideCaret = false;
ShowRightMouseMeun(e, mouse_pt);
m_HexMousePos.iPos = (i_start_display + i_Select_Row) * i_row_display + iy;
m_HexMousePos.iArea = 1;
m_HexMousePos.bLeftPos = false;
m_HexMousePos.bRightPos = true;
break;
}
i_data_offset += i_font_width + i_row_staff;
}
//如果點選區域超過最大值,則不顯示
if (m_HexMousePos.iPos != -1 &&
m_HexMousePos.iPos >= GetDataLength())
{
OnHideCaret();
}
}
else
{
OnHideCaret();
}
#endregion
}
}
/// <summary>
/// 處理滑鼠按鍵彈起訊息
/// </summary>
/// <param name="e"></param>
protected override void OnMouseUp(MouseEventArgs e)
{
//如果資料為空,則直接返回
if (m_HexEditData == null)
{
return;
}
this.Focus();
return;
}
// 摘要:
// 處理垂直拉條的移動
private void m_VScrollBar_Scroll(object obj, ScrollEventArgs e)
{
if (i_start_display != e.NewValue)
{
i_start_display = e.NewValue;
if (!m_IsHideCaret)
{
OnHideCaret();
m_IsHideCaret = true;
}
m_HexMousePos.iPos = -1;
m_HexMousePos.iArea = -1;
m_HexMousePos.bLeftPos = false;
m_HexMousePos.bRightPos = false;
this.Invalidate();
}
}
/// <summary>
/// 實現滑鼠中間按鈕滾動
/// </summary>
/// <param name="e"></param>
protected override void OnMouseWheel(MouseEventArgs e)
{
//表明像下滾動
if (e.Delta == -120)
{
if (i_start_display < this.m_VScrollBar.Maximum)
{
i_start_display += 1;
this.m_VScrollBar.Value = i_start_display;
this.Invalidate();
}
}
//表明向上滾動
else if (e.Delta == 120)
{
if (i_start_display > 0)
{
i_start_display -= 1;
this.m_VScrollBar.Value = i_start_display;
this.Invalidate();
}
}
else
{
base.OnMouseWheel(e);
}
if (!m_IsHideCaret)
{
OnHideCaret();
m_IsHideCaret = true;
}
m_HexMousePos.iPos = -1;
m_HexMousePos.iArea = -1;
m_HexMousePos.bLeftPos = false;
m_HexMousePos.bRightPos = false;
}
#endregion
#region 字型相關函式
/// <summary>
/// 計算字型的大小
/// </summary>
/// <param name="strText"></param>
/// <param name="font"></param>
/// <returns></returns>
private SizeF CalcFontSize(string strText, Font font)
{
Graphics g = this.CreateGraphics();
SizeF sizeF = g.MeasureString(strText, font);
g.Dispose();
return sizeF;
}
/// <summary>
/// 獲取字型的寬度
/// </summary>
/// <returns></returns>
private int GetFontSizeFWidth()
{
SizeF size = CalcFontSize("00", hep.HexBackgroundFont);
return (int)size.Width + 1;
}
/// <summary>
/// 獲取字型的高度
/// </summary>
/// <returns></returns>
private int GetFontSizeFHeigth()
{
SizeF size = CalcFontSize("00", hep.HexBackgroundFont);
return (int)size.Height + 1;
}
#endregion
#region 資料轉換函式
// 摘要:
// 將一個Hex字元轉換為8位元組的byte
private byte HexCharValue(byte b)
{
if ('0' <= b && b <= '9')
{
return (byte)(b - '0');
}
else if ('A' <= b && b <= 'F')
{
return (byte)(b - 'A' + 10);
}
else if (97 <= b && b <= 105)
{
return (byte)(b - 97 + 1);
}
else
{
return 0;
}
}
/// <summary>
/// 將字串轉換為陣列
/// </summary>
/// <param name="strData"></param>
/// <param name="dt"></param>
/// <returns></returns>
private byte[] ConvertStringToByte(string strData, HexEditProperties.EncodingType dt)
{
if (string.IsNullOrEmpty(strData))
{
return null;
}
if (dt == HexEditProperties.EncodingType.ANSI)
{
char[] cData = strData.ToCharArray();
byte[] bData = new byte[cData.Length];
for (int ix = 0; ix < cData.Length; ix++)
{
bData[ix] = Convert.ToByte(cData[ix]);
}
return bData;
}
else if (dt == HexEditProperties.EncodingType.Unicond)
{
return Encoding.GetEncoding("Unicode").GetBytes(strData);
}
else
{
return null;
}
}
// 摘要:
// 將是byte陣列轉換成string字串
private string ConvertByteToStirng(byte[] bData, HexEditProperties.EncodingType dt)
{
if (dt == HexEditProperties.EncodingType.ANSI)
{
char[] cData = new char[bData.Length];
Array.Copy(bData, cData, bData.Length);
return new string(cData);
}
else if (dt == HexEditProperties.EncodingType.Unicond)
{
return Encoding.GetEncoding("Unicode").GetString(bData);
}
else
{
return null;
}
}
// 摘要:
// 判斷傳入的char是否為漢字
private bool IsChineseChar(char character)
{
//漢字的範圍在4E00 - 9FA5之間,所以只需要判斷是否在此空間內即可
Regex reg = new Regex(@"[\u4e00-\u9fa5]");
string strData = character.ToString();
if (reg.IsMatch(strData))
{
return true;
}
else
{
return false;
}
}
// 摘要:
// 將是漢字的字元轉換成byte陣列
private byte[] ConvertChineseToByte(char character, HexEditProperties.EncodingType dt)
{
if (dt == HexEditProperties.EncodingType.ANSI)
{
return Encoding.GetEncoding("GB2312").GetBytes(character.ToString());
}
else if (dt == HexEditProperties.EncodingType.Unicond)
{
return Encoding.GetEncoding("Unicode").GetBytes(character.ToString());
}
else
{
return null;
}
}
#endregion
#region 獲取位置資訊函式
/// <summary>
/// 獲取控制元件顯示的最大行數
/// </summary>
/// <returns></returns>
private int GetControlMaxRowShowCount()
{
//獲取字型的寬度及長度
SizeF sizef = CalcFontSize("00", hep.HexBackgroundFont);
int i_font_width = (int)sizef.Width + 1;
int i_font_height = (int)sizef.Height + 1;
//計算控制元件最大可顯示的行數
int i_height = 0;
if (hep.IsSupportDisplayHexHead)
{
i_height = this.Height - hep.HexOutLineWidth - hep.HexHeadHeight;
}
else
{
i_height = this.Height - hep.HexOutLineWidth;
}
int iMaxDataRow = (int)(i_height / (i_font_height + i_Column_staff));
return iMaxDataRow;
}
/// <summary>
/// 獲取資料需要顯示的行數
/// </summary>
/// <returns></returns>
private int GetDataNeedDisplayRowShowCount()
{
if (string.IsNullOrEmpty(m_HexEditData))
{
return -1;
}
//計算實際的行數
int i_data_row = 0;
int i_data_mod = 0;
//將資料轉換為陣列
byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);
//將字串轉換為陣列
if (bt != null && bt.Length > 0)
{
i_data_row = bt.Length / i_row_display;
i_data_mod = bt.Length % i_row_display;
}
if (i_data_mod != 0)
{
i_data_row += 1;
}
return i_data_row;
}
/// <summary>
/// 獲取資料的長度
/// </summary>
/// <returns></returns>
private int GetDataLength()
{
if (string.IsNullOrEmpty(m_HexEditData))
{
return -1;
}
//將資料轉換為陣列
byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);
return bt.Length;
}
/// <summary>
/// 獲取指定位置的資料
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
private byte GetDataByPos(int pos)
{
//將資料轉換為陣列
byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);
return bt[pos];
}
/// <summary>
/// 獲取所在位置
/// </summary>
/// <returns></returns>
private int GetColumnPos()
{
//查詢在第幾列
int iColumn = 0;
if (m_HexMousePos.iPos % i_row_display != 0)
{
iColumn = m_HexMousePos.iPos % i_row_display;
}
else
{
iColumn = 0;
}
return iColumn;
}
/// <summary>
/// 獲取資料資料所在行的起始位置
/// </summary>
/// <returns></returns>
private Point GetDataAtRowStartPos()
{
Point pt_row;
int i_offset = 0;
int i_font_height = GetFontSizeFHeigth();
if (hep.IsSupportHexAddress)
{
i_offset = hep.HexOutLineWidth / 2 + hep.HexAddressWidth;
}
else
{
i_offset = hep.HexOutLineWidth / 2;
}
int height = 0;
if (hep.IsSupportDisplayHexHead)
{
height = hep.HexOutLineWidth / 2 + hep.HexHeadHeight + i_Select_Row * (i_font_height + i_Column_staff);
}
else
{
height = hep.HexOutLineWidth / 2 + i_Select_Row * (i_font_height + i_Column_staff);
}
pt_row = new Point(i_offset, height);
return pt_row;
}
/// <summary>
/// 獲取位址列的起始位置
/// </summary>
/// <returns></returns>
private Point GetAddressAreaStartPos()
{
Point pt;
if (hep.IsSupportDisplayHexHead)
{
pt = new Point(hep.HexOutLineWidth / 2, hep.HexHeadHeight + hep.HexOutLineWidth / 2);
}
else
{
pt = new Point(hep.HexOutLineWidth / 2, hep.HexOutLineWidth / 2);
}
return pt;
}
/// <summary>
/// 獲取資料區域的起始位置
/// </summary>
/// <returns></returns>
private Point GetDataAreaStartPos()
{
Point pt;
int i_pt_width = 0;
int i_pt_height = 0;
//判定是否顯示Head欄
if (hep.IsSupportDisplayHexHead)
{
i_pt_height = hep.HexHeadHeight + hep.HexOutLineWidth / 2;
}
else
{
i_pt_height = hep.HexOutLineWidth / 2;
}
//判定是否支援顯示位址列
if (hep.IsSupportHexAddress)
{
i_pt_width = hep.HexAddressWidth + hep.HexOutLineWidth / 2;
}
else
{
i_pt_width = hep.HexOutLineWidth / 2;
}
pt = new Point(i_pt_width, i_pt_height);
return pt;
}
/// <summary>
/// 獲取資料區域的高度
/// </summary>
/// <returns></returns>
private int GetDataAreaHeight()
{
int i_height = 0;
if (hep.IsSupportDisplayHexHead)
{
i_height = this.Height - hep.HexOutLineWidth - hep.HexHeadHeight;
}
else
{
i_height = this.Height - hep.HexOutLineWidth;
}
return i_height;
}
#endregion
#region 垂直滾動條顯示函式
/// <summary>
/// 判定垂直滾動條是否需要顯示
/// </summary>
private void VScrollBarDisplay()
{
//判定起始點
Point pt = GetDataAreaStartPos();
//計算控制元件最大可顯示的行數
SizeF sizef = CalcFontSize("00", hep.HexBackgroundFont);
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
int iMaxDataRow = GetControlMaxRowShowCount();
//計算實際資料可顯示的行數
int i_data_row = GetDataNeedDisplayRowShowCount();
if (i_data_row > iMaxDataRow)
{
this.m_VScrollBar.Visible = true;
this.m_VScrollBar.Enabled = true;
//設定控制元件位置
this.m_VScrollBar.Location = new Point(this.Width - hep.HexOutLineWidth - i_Scroll_Width, pt.Y);
this.m_VScrollBar.Size = new Size(i_Scroll_Width, GetDataAreaHeight());
//設定控制元件的最大值
this.m_VScrollBar.LargeChange = 1;
//this.m_VScrollBar.Maximum = i_data_row / iMaxDataRow + i_data_row % iMaxDataRow;
this.m_VScrollBar.Maximum = i_data_row - iMaxDataRow;
}
else
{
this.m_VScrollBar.Visible = false;
this.m_VScrollBar.Enabled = false;
}
}
#endregion
#region Caret函式
// 摘要:
// 建立Caret
private void OnCreateCaret()
{
//如果沒有建立Caret,則建立
if (!m_IsCreateCaret)
{
m_IsCreateCaret = true;
CreateCaret(this.Handle, IntPtr.Zero, (int)hep.HexBackgroundFont.Size, hep.HexBackgroundFont.Height + i_Column_staff);
}
}
// 摘要:
// 隱藏Caret,並設定相關位置
private void OnHideCaret()
{
if (!m_IsHideCaret)
{
HideCaret(this.Handle);
m_IsHideCaret = true;
}
m_HexMousePos.iPos = -1;
m_HexMousePos.iArea = -1;
m_HexMousePos.bLeftPos = false;
m_HexMousePos.bRightPos = false;
}
// 摘要:
// 重新生成Caret
private void CreateNewCaret()
{
//獲取列
int iColumn = GetColumnPos();
//獲取字型寬度及高度
int i_font_Height = GetFontSizeFHeigth();
int i_font_Width = GetFontSizeFWidth();
//獲取所在行的起始位置
Point pt = GetDataAtRowStartPos();
//如果建立了Caret,則銷燬
if (m_IsCreateCaret)
{
DestroyCaret();
m_IsCreateCaret = false;
}
//建立Caret
OnCreateCaret();
m_IsCreateCaret = true;
int iWidth = 0;
if (m_HexMousePos.bLeftPos)
{
iWidth = pt.X + iColumn * (i_font_Width + i_row_staff) + i_row_staff;
}
else
{
iWidth = pt.X + iColumn * (i_font_Width + i_row_staff) + i_row_staff + i_font_Width / 2;
}
//設定位置
SetCaretPos(iWidth, pt.Y);
ShowCaret(this.Handle);
}
#endregion
#region 方向鍵函式
// 摘要:
// Caret向左移動
private void OnVK_Left()
{
if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
{
this.Focus();
//表明在Data區
if (m_HexMousePos.iArea == 1)
{
//獲取字型的寬度及長度
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
//查詢在第幾列
int iColumn = GetColumnPos();
//獲取所在行的啟動資訊
Point pt_row = GetDataAtRowStartPos();
//表示在每行的起始位置
Point pt = new Point();
if (iColumn == 0)
{
//表明在第一個位元組的右部
if (m_HexMousePos.bRightPos)
{
pt.X = pt_row.X + i_row_staff;
pt.Y = pt_row.Y;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
//表明在第一個位元組的左部
if (m_HexMousePos.bLeftPos)
{
if (i_Select_Row > 0)
{
i_Select_Row -= 1;
pt.X = pt_row.X + i_row_display * (i_font_width + i_row_staff) - i_font_width / 2;
pt.Y = pt_row.Y - i_font_height - i_Column_staff;
m_HexMousePos.iPos -= 1;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
else if (i_Select_Row == 0 && i_start_display > 0)
{
i_Select_Row = 0;
i_start_display -= 1;
m_VScrollBar.Value = i_start_display;
this.Invalidate();
pt.X = pt_row.X + i_row_display * (i_font_width + i_row_staff) - i_font_width / 2;
pt.Y = pt_row.Y;
m_HexMousePos.iPos -= 1;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
}
}
//表示不在每行的起始位置
else
{
//表明在位元組的右部
if (m_HexMousePos.bRightPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
pt.Y = pt_row.Y;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
//表明在位元組的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = pt_row.X + (iColumn - 1) * (i_font_width + i_row_staff) + i_row_staff + i_font_width - i_font_width / 2;
pt.Y = pt_row.Y;
m_HexMousePos.iPos -= 1;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
}
}
}
}
// 摘要:
// Caret向右移動
private void OnVK_Right()
{
if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
{
this.Focus();
//表明在Data區
if (m_HexMousePos.iArea == 1)
{
//獲取字型的寬度及長度
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
//查詢在第幾列
int iColumn = GetColumnPos();
//獲取所在行的啟動資訊
Point pt_row = GetDataAtRowStartPos();
//表明在最後一個位元組
Point pt = new Point();
if (iColumn == i_row_display - 1)
{
//表明在位元組的右部
if (m_HexMousePos.bRightPos)
{
//計算控制元件最大可顯示的行數
int iMaxDataRow = GetControlMaxRowShowCount();
//計算實際的行數
int i_data_row = GetDataNeedDisplayRowShowCount();
if (i_Select_Row < iMaxDataRow - 1)
{
i_Select_Row++;
pt.X = pt_row.X + i_row_staff;
pt.Y = pt_row.Y + i_font_height + i_Column_staff;
m_HexMousePos.iPos += 1;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
else if (i_Select_Row == iMaxDataRow - 1 && i_data_row - i_start_display - iMaxDataRow > 0)
{
i_start_display += 1;
m_VScrollBar.Value = i_start_display;
this.Invalidate();
pt.X = pt_row.X + i_row_staff;
pt.Y = pt_row.Y;
m_HexMousePos.iPos += 1;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
return;
}
}
//表明在位元組的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
pt.Y = pt_row.Y;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
}
else
{
//表明在位元組的右部
if (m_HexMousePos.bRightPos)
{
//判定是否在最後一個位元組
if (m_HexMousePos.iPos + 1 >= GetDataLength())
{
return;
}
pt.X = pt_row.X + (iColumn + 1) * (i_font_width + i_row_staff) + i_row_staff;
pt.Y = pt_row.Y;
m_HexMousePos.iPos += 1;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
//表明在位元組的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
pt.Y = pt_row.Y;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
}
}
}
}
// 摘要:
// Caret向下移動
private void OnVK_Down()
{
if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
{
this.Focus();
//表明在Data區
if (m_HexMousePos.iArea == 1)
{
//獲取字型的寬度及長度
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
//查詢在第幾列
int iColumn = GetColumnPos();
//獲取所在行的啟動資訊
Point pt_row = GetDataAtRowStartPos();
//計算最大顯示行數
int iMaxDataRow = GetControlMaxRowShowCount();
//計算實際資料可顯示的行數
int i_data_row = GetDataNeedDisplayRowShowCount();
//進行判定
Point pt = new Point();
if (m_HexMousePos.iPos + i_row_display < GetDataLength())
{
if (i_Select_Row < iMaxDataRow - 1)
{
i_Select_Row += 1;
//表明在第一個位元組的右部
if (m_HexMousePos.bRightPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
pt.Y = pt_row.Y + i_font_height + i_Column_staff;
m_HexMousePos.iPos += i_row_display;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
//表明在第一個位元組的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
pt.Y = pt_row.Y + i_font_height + i_Column_staff;
m_HexMousePos.iPos += i_row_display;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
}
else
{
i_start_display += 1;
//表明在第一個位元組的右部
if (m_HexMousePos.bRightPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
pt.Y = pt_row.Y;
m_HexMousePos.iPos += i_row_display;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.m_VScrollBar.Value = i_start_display;
this.Invalidate();
return;
}
//表明在第一個位元組的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
pt.Y = pt_row.Y;
m_HexMousePos.iPos += i_row_display;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.m_VScrollBar.Value = i_start_display;
this.Invalidate();
return;
}
}
}
}
}
}
// 摘要:
// Caret向上移動
private void OnVK_Up()
{
if (m_HexMousePos.iPos != -1 && m_HexMousePos.iArea != -1)
{
//表明在Data區
if (m_HexMousePos.iArea == 1)
{
//獲取字型的寬度及長度
int i_font_width = GetFontSizeFWidth();
int i_font_height = GetFontSizeFHeigth();
//查詢在第幾列
int iColumn = GetColumnPos();
//獲取所在行的啟動資訊
Point pt_row = GetDataAtRowStartPos();
//計算最大顯示行數
int iMaxDataRow = GetControlMaxRowShowCount();
//計算實際資料可顯示的行數
int i_data_row = GetDataNeedDisplayRowShowCount();
//進行判定
Point pt = new Point();
if (m_HexMousePos.iPos - i_row_display > 0)
{
if (i_Select_Row > 0)
{
i_Select_Row -= 1;
//表明在第一個位元組的右部
if (m_HexMousePos.bRightPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
pt.Y = pt_row.Y - i_font_height - i_Column_staff;
m_HexMousePos.iPos -= i_row_display;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
//表明在第一個位元組的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
pt.Y = pt_row.Y - i_font_height - i_Column_staff;
m_HexMousePos.iPos -= i_row_display;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.Invalidate();
return;
}
}
else
{
i_start_display -= 1;
//表明在第一個位元組的右部
if (m_HexMousePos.bRightPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff + i_font_width / 2;
pt.Y = pt_row.Y;
m_HexMousePos.iPos -= i_row_display;
m_HexMousePos.bRightPos = true;
m_HexMousePos.bLeftPos = false;
SetCaretPos(pt.X, pt.Y);
this.m_VScrollBar.Value = i_start_display;
this.Invalidate();
return;
}
//表明在第一個位元組的左部
if (m_HexMousePos.bLeftPos)
{
pt.X = pt_row.X + iColumn * (i_font_width + i_row_staff) + i_row_staff;
pt.Y = pt_row.Y;
m_HexMousePos.iPos -= i_row_display;
m_HexMousePos.bRightPos = false;
m_HexMousePos.bLeftPos = true;
SetCaretPos(pt.X, pt.Y);
this.m_VScrollBar.Value = i_start_display;
this.Invalidate();
return;
}
}
}
}
}
}
#endregion
#region 公開函式
/// <summary>
/// 向控制元件中新增資料
/// </summary>
/// <param name="strData"></param>
public void AddData(string strData)
{
if (string.IsNullOrEmpty(strData))
{
return;
}
m_HexEditData = strData;
VScrollBarDisplay();
this.Invalidate();
}
/// <summary>
/// 向控制元件中新增資料
/// </summary>
/// <param name="strData"></param>
public void AddData(byte[] bdata)
{
if (bdata == null)
{
return;
}
m_HexEditData = ConvertByteToStirng(bdata, hep.HexDataType);
VScrollBarDisplay();
this.Invalidate();
}
/// <summary>
/// 獲取控制元件資料
/// </summary>
/// <returns></returns>
public string GetStringData()
{
return m_HexEditData;
}
/// <summary>
/// 獲取控制元件資料
/// </summary>
/// <returns></returns>
public byte[] GetByteArrayData()
{
return ConvertStringToByte(m_HexEditData, hep.HexDataType);
}
#endregion
#region 動態載入函式
[DllImport("user32.dll")]
static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
[DllImport("user32.dll")]
static extern bool ShowCaret(IntPtr hWnd);
[DllImport("User32.dll")]
static extern bool HideCaret(IntPtr hWnd);
[DllImport("User32.dll")]
static extern bool SetCaretPos(int x, int y);
[DllImport("user32.dll")]
static extern bool DestroyCaret();
#endregion
#region 選單響應函式
// 摘要:
// 顯示右鍵選單
private void ShowRightMouseMeun(MouseEventArgs e, Point pt)
{
if (e.Button == MouseButtons.Right && hep.IsSupportDisplayMenu)
{
m_HexMenu.Show(this, pt);
}
}
// 摘要:
// 插入一個string
private void MenuItem0_Click(object obj, EventArgs e)
{
Form f1 = new Form();
//獲取字型的高度及寬度
int i_font_height = GetFontSizeFHeigth();
int i_font_width = GetFontSizeFWidth();
//查詢在第幾列
int iColumn = GetColumnPos();
//獲取起始位置
Point pt = GetDataAtRowStartPos();
f1.Text = "Insert a string...";
f1.ShowIcon = false;
f1.MaximizeBox = false;
f1.MinimizeBox = false;
f1.StartPosition = FormStartPosition.Manual;
f1.FormBorderStyle = FormBorderStyle.FixedDialog;
f1.Size = new System.Drawing.Size(470, 300);
f1.Location = new System.Drawing.Point(pt.X + iColumn * (i_font_width + i_row_staff), pt.Y);
Label lb = new Label();
lb.Text = "插入string的長度: ";
lb.Location = new Point(20, 23);
lb.Size = new System.Drawing.Size(110, 20);
lb.Visible = true;
f1.Controls.Add(lb);
TextBox tb = new TextBox();
tb.Location = new System.Drawing.Point(130, 20);
tb.Size = new System.Drawing.Size(200, 20);
tb.Visible = true;
f1.Controls.Add(tb);
Label lb1 = new Label();
lb1.Text = "插入string的內容: ";
lb1.Location = new Point(20, 50);
lb1.Size = new System.Drawing.Size(110, 20);
lb1.Visible = true;
f1.Controls.Add(lb1);
TextBox tb1 = new TextBox();
tb1.Location = new System.Drawing.Point(20, 75);
tb1.Size = new System.Drawing.Size(310, 180);
tb1.Visible = true;
tb1.Multiline = true;
f1.Controls.Add(tb1);
Button button = new Button();
button.Text = "OK";
button.Location = new Point(350, 18);
button.Size = new System.Drawing.Size(100, 30);
button.Visible = true;
button.Click += new System.EventHandler(OK_Click);
f1.Controls.Add(button);
Button button1 = new Button();
button1.Text = "Cancle";
button1.Location = new Point(350, 50);
button1.Size = new System.Drawing.Size(100, 30);
button1.Visible = true;
button1.Click += new System.EventHandler(CANCLE_Click);
f1.Controls.Add(button1);
if (DialogResult.OK == f1.ShowDialog())
{
string strLength = tb.Text;
string strContext = tb1.Text;
if (string.IsNullOrEmpty(strLength) ||
string.IsNullOrEmpty(strContext))
{
return;
}
if (uint.Parse(strLength) != strContext.Length)
{
return;
}
byte[] bSource = ConvertStringToByte(m_HexEditData, hep.HexDataType);
byte[] bt = ConvertStringToByte(strContext, hep.HexDataType);
int i_copy_data_length = 0;
if (m_HexMousePos.iPos + bt.Length >= bSource.Length)
{
i_copy_data_length = bSource.Length - m_HexMousePos.iPos;
}
else
{
i_copy_data_length = bt.Length;
}
//拷貝資料
Array.Copy(bt, 0, bSource, m_HexMousePos.iPos, i_copy_data_length);
m_HexEditData = ConvertByteToStirng(bSource, hep.HexDataType);
this.Invalidate();
}
CreateNewCaret();
}
// 摘要:
// 響應彈出FORM的OK/CANCLE按鈕
private void OK_Click(object obj, EventArgs e)
{
Button bt = (Button)obj;
Form f1 = bt.Parent as Form;
f1.DialogResult = DialogResult.OK;
}
private void CANCLE_Click(object obj, EventArgs e)
{
Button bt = (Button)obj;
Form f1 = bt.Parent as Form;
f1.DialogResult = DialogResult.Cancel;
}
// 摘要:
// 從剪貼簿上覆制
private void MenuItem1_Click(object obj, EventArgs e)
{
IDataObject ido = Clipboard.GetDataObject();
if (ido.GetDataPresent(DataFormats.Text))
{
string strData = (string)ido.GetData(DataFormats.Text);
byte[] bSource = ConvertStringToByte(m_HexEditData, hep.HexDataType);
byte[] bt = ConvertStringToByte(strData, hep.HexDataType);
int i_copy_data_length = 0;
if (m_HexMousePos.iPos + bt.Length >= bSource.Length)
{
i_copy_data_length = bSource.Length - m_HexMousePos.iPos;
}
else
{
i_copy_data_length = bt.Length;
}
//拷貝資料
Array.Copy(bt, 0, bSource, m_HexMousePos.iPos, i_copy_data_length);
m_HexEditData = ConvertByteToStirng(bSource, hep.HexDataType);
this.Invalidate();
}
}
// 摘要:
// 從檔案中載入資料
private void MenuItem2_Click(object obj, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "all file (*.*)|*.*";
ofd.FilterIndex = 1;
ofd.RestoreDirectory = true;
ofd.FileName = null;
if (DialogResult.OK == ofd.ShowDialog())
{
string strFilePath = ofd.FileName;
byte[] bSource = ConvertStringToByte(m_HexEditData, hep.HexDataType);
byte[] bt = ReadHexDataFromFile(strFilePath);
int i_copy_data_length = 0;
if (m_HexMousePos.iPos + bt.Length >= bSource.Length)
{
i_copy_data_length = bSource.Length - m_HexMousePos.iPos;
}
else
{
i_copy_data_length = bt.Length;
}
//拷貝資料
Array.Copy(bt, 0, bSource, m_HexMousePos.iPos, i_copy_data_length);
m_HexEditData = ConvertByteToStirng(bSource, hep.HexDataType);
this.Invalidate();
}
CreateNewCaret();
}
// 摘要:
// 從檔案中讀取十六進位制資料流
private byte[] ReadHexDataFromFile(string path)
{
if (!File.Exists(path))
{
return null;
}
FileStream fs = new FileStream(path, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] bt = br.ReadBytes((int)fs.Length);
br.Close();
return bt;
}
// 摘要:
// 將資料儲存至檔案
private void MenuItem3_Click(object obj, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "all file (*.*)|*.*";
sfd.FilterIndex = 1;
sfd.RestoreDirectory = true;
sfd.FileName = null;
if (DialogResult.OK == sfd.ShowDialog())
{
byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);
WriteHexDataToFile(sfd.FileName, bt);
}
CreateNewCaret();
}
// 摘要:
// 將資料寫入到檔案中
private bool WriteHexDataToFile(string path, byte[] bt)
{
if (File.Exists(path))
{
if (DialogResult.OK != MessageBox.Show(path + " 檔案已經存在,是否替換?"))
{
return false;
}
}
FileStream fs = new FileStream(path, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bt, 0, bt.Length);
bw.Close();
return true;
}
// 摘要:
// 清空資料
private void MenuItem4_Click(object obj, EventArgs e)
{
byte[] bt = ConvertStringToByte(m_HexEditData, hep.HexDataType);
for (int ix = 0; ix < bt.Length; ix++)
{
bt[ix] = 0;
}
m_HexEditData = ConvertByteToStirng(bt, hep.HexDataType);
this.Invalidate();
}
#endregion
}
}
相關文章
- 讓HEXEDIT2.54顯示漢字(5千字)
- 【C#】Learn C# in X minutesC#
- [C#]C#中字串的操作C#字串
- [C#]C#時間日期操作C#
- C#C#
- 一口氣破解ResTools的四個軟體:ResScope1.35、freeRes0.94、HexEdit0.20、GetVBRes0.51全過程 (10千字)REST
- C# 語言歷史版本特性(C# 1.0到C# 8.0彙總)C#
- C#語言歷史版本特性(C# 1.0到C# 8.0彙總)C#
- C# 9.0 正式釋出了(C# 9.0 on the record)C#
- C# ActivatorC#
- C# on DevCloudC#devCloud
- C# DbHeplerC#
- C# FirstOrDefaultC#
- C# 概念C#
- C#反射C#反射
- c# 方法C#
- c# ArraySegmentC#
- C# dynamicC#
- C# is與asC#
- Thrift c#C#
- c# abstractC#
- C# BackgroudWorkerC#
- XMLOperator[C#]XMLC#
- c# listviewC#View
- C#字串C#字串
- 《Effective C#》C#
- C#方法C#
- C# 物件C#物件
- C#特性C#
- c# channelC#
- C# ViewStateC#View
- C# 打包C#
- 重學c#系列——c#執行原理(二)C#
- C#神器"BlockingCollection"類實現C#神仙操作C#BloCGC
- C#入門之C#特點及HelloWorld程式C#
- C#基礎系列--C#中委託與事件(三)C#事件
- C#基礎系列--C#中委託與事件(一)C#事件
- 【C#開發】C#的協變和逆變C#