1.line和多边形增加删除功能
2.多张合并时 同步移动ROI 3.多张合并时展示重构 4.增加多张合并时同时复制粘贴 5.增加快捷键复制粘贴
This commit is contained in:
parent
38df215f45
commit
f7dbb84124
2
src/PBAnaly/MainForm.Designer.cs
generated
2
src/PBAnaly/MainForm.Designer.cs
generated
@ -659,7 +659,7 @@
|
||||
this.thunderLabel1.Name = "thunderLabel1";
|
||||
this.thunderLabel1.Size = new System.Drawing.Size(200, 16);
|
||||
this.thunderLabel1.TabIndex = 19;
|
||||
this.thunderLabel1.Text = "PBAnaly v0.1.7";
|
||||
this.thunderLabel1.Text = "PBAnaly v0.1.7rc2";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
|
@ -447,7 +447,7 @@ namespace PBAnaly
|
||||
bioanalyBool = true;
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.Arrangement = false;
|
||||
item.Value.Arrangement = 0;
|
||||
item.Value.WindowAdaptive();
|
||||
}
|
||||
}
|
||||
@ -456,7 +456,7 @@ namespace PBAnaly
|
||||
bioanalyBool = false;
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.Arrangement = false;
|
||||
item.Value.Arrangement = 0;
|
||||
item.Value.WindowNormalAdaptive();
|
||||
}
|
||||
}
|
||||
@ -511,14 +511,15 @@ namespace PBAnaly
|
||||
else if(data_row >=5 && data_row <=9) data_row = 9;
|
||||
data_tab.RowCount = data_row*2;
|
||||
data_tab.ColumnCount = data_col + 1;
|
||||
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < data_row; i++)
|
||||
{
|
||||
if(i % 2==0)
|
||||
data_tab.RowStyles.Add(new RowStyle(SizeType.Percent, 100f / data_row));
|
||||
else
|
||||
data_tab.RowStyles.Add(new RowStyle(SizeType.Absolute, 20));
|
||||
data_tab.RowStyles.Add(new RowStyle(SizeType.Absolute, 40));
|
||||
}
|
||||
for (int i = 0; i < data_col; i++)
|
||||
{
|
||||
@ -534,6 +535,7 @@ namespace PBAnaly
|
||||
foreach (var bname in bioanalyName)
|
||||
{
|
||||
var item = bioanalysisMannages[bname];
|
||||
item.Arrangement = 1;
|
||||
if (index == bioanalysisMannages.Count - 1)
|
||||
{
|
||||
pl_right.Controls.Add(item.GetBioanayImagePanel);
|
||||
@ -545,7 +547,7 @@ namespace PBAnaly
|
||||
data_right_bar.Dock = DockStyle.Fill;
|
||||
data_tab.Controls.Add(data_right_bar, data_tab.ColumnCount - 1, 0);
|
||||
data_tab.SetRowSpan(data_right_bar, data_row);
|
||||
item.Arrangement = true;
|
||||
item.Arrangement = 2;
|
||||
|
||||
}
|
||||
index++;
|
||||
@ -571,6 +573,7 @@ namespace PBAnaly
|
||||
else
|
||||
{
|
||||
bioanalyBool = false;
|
||||
if (data_tab == null) return;
|
||||
data_tab.Controls.Clear();
|
||||
DataProcess_panel.Controls.Clear();
|
||||
pl_right.Controls.Clear();
|
||||
@ -584,7 +587,7 @@ namespace PBAnaly
|
||||
pl_right.Controls.Add(item.Value.GetBioanayImagePanel);
|
||||
index++;
|
||||
}
|
||||
item.Value.Arrangement = false;
|
||||
item.Value.Arrangement = 0;
|
||||
DataProcess_panel.Controls.Add(item.Value.GetImagePanel);
|
||||
item.Value.Rifresh();
|
||||
item.Value.GetImagePanel.BringToFront();
|
||||
|
@ -70,12 +70,16 @@ namespace PBAnaly.Module
|
||||
}
|
||||
#endregion
|
||||
#region 变量
|
||||
private ShapeForm curTmpDownShape = ShapeForm.None;// 用于快捷键 临时确认点击了那个矩形
|
||||
private ShapeForm curShape = ShapeForm.None;
|
||||
private int curTmpDownShapeIndex;
|
||||
private int curShapeIndex;
|
||||
private System.Drawing.Point curTmpDownShapePoint;
|
||||
private System.Drawing.Point curShapePoint;
|
||||
|
||||
public bool IsActive { get; set; } // 当前窗口是否在活跃状态 用来判断是否需要操作
|
||||
public int ImageIndex { get; set; }// 图片加载进来的序号
|
||||
public bool Arrangement { get; set; }
|
||||
public int Arrangement { get; set; } // 0:代表单张图 1:代表是合并图图但不做处理 2:代表是合并图 并且为处理图
|
||||
private Dictionary<string, BioanalysisMannage> bioanalysisMannages;
|
||||
public string path { get; set; }
|
||||
private string mark_path;
|
||||
@ -471,6 +475,7 @@ namespace PBAnaly.Module
|
||||
imagePaletteForm.fb_fixSetting.Click += Fb_fixSetting_Click;
|
||||
imagePaletteForm.cb_continuous.CheckedChanged += Cb_continuous_CheckedChanged;
|
||||
|
||||
KeyboardListener.Register(OnKeyPressed); // 创建键盘钩子
|
||||
}
|
||||
|
||||
|
||||
@ -501,7 +506,7 @@ namespace PBAnaly.Module
|
||||
var t = tifFiles[0].Split("\\");
|
||||
if (t.Length > 2)
|
||||
{
|
||||
imagePanel.SetButtomName($"{t[t.Length - 2]}");
|
||||
imagePanel.SetButtomName($"{t[t.Length - 2]} {image_mark_L16.Width} x {image_mark_L16.Height}");
|
||||
}
|
||||
|
||||
}
|
||||
@ -760,8 +765,17 @@ namespace PBAnaly.Module
|
||||
#region 事件
|
||||
private void Wdb_title_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.pl_right.Controls.Clear();
|
||||
this.pl_right.Controls.Add(this.imagePaletteForm);
|
||||
if (Arrangement == 2 || Arrangement == 0)
|
||||
{
|
||||
this.pl_right.Controls.Clear();
|
||||
this.pl_right.Controls.Add(this.imagePaletteForm);
|
||||
}
|
||||
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.IsActive = false;
|
||||
}
|
||||
IsActive = true;
|
||||
this.imagePanel.BringToFront();
|
||||
}
|
||||
private void Cb_scientific_CheckedChanged(object sender, AntdUI.BoolEventArgs e)
|
||||
@ -793,7 +807,7 @@ namespace PBAnaly.Module
|
||||
}
|
||||
private void Dtb_brightness_ValueChanged()
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -808,7 +822,7 @@ namespace PBAnaly.Module
|
||||
}
|
||||
private void Dtb_opacity_ValueChanged()
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -823,7 +837,7 @@ namespace PBAnaly.Module
|
||||
}
|
||||
private void Nud_opacity_ValueChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -839,7 +853,7 @@ namespace PBAnaly.Module
|
||||
|
||||
private void Nud_brightness_ValueChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -854,7 +868,7 @@ namespace PBAnaly.Module
|
||||
}
|
||||
private void Nud_colorMin_ValueChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -870,7 +884,7 @@ namespace PBAnaly.Module
|
||||
|
||||
private void Nud_colorMax_ValueChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -886,7 +900,7 @@ namespace PBAnaly.Module
|
||||
|
||||
private void Dtb_colorMin_ValueChanged()
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -902,7 +916,7 @@ namespace PBAnaly.Module
|
||||
|
||||
private void Dtb_colorMax_ValueChanged()
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -917,7 +931,7 @@ namespace PBAnaly.Module
|
||||
}
|
||||
private void Cb_colortable_SelectedIndexChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -941,7 +955,7 @@ namespace PBAnaly.Module
|
||||
// 绘制直线
|
||||
if ((startPoint != System.Drawing.Point.Empty && endPoint != System.Drawing.Point.Empty))
|
||||
{
|
||||
if (Arrangement)
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
@ -1224,7 +1238,18 @@ namespace PBAnaly.Module
|
||||
rab.pdinfovc = curpdinfovc;
|
||||
imagePaletteForm.SetInfo = "w:" + rab.rect.Width.ToString() + "h:" + rab.rect.Height.ToString();
|
||||
// 完成绘制并保存矩形
|
||||
rectangles.Add(rab);
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.rectangles.Add(rab);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rectangles.Add(rab);
|
||||
}
|
||||
|
||||
currentRectangle = null;
|
||||
drawRect = false;
|
||||
imagePanel.image_pl.Invalidate();
|
||||
@ -1262,7 +1287,18 @@ namespace PBAnaly.Module
|
||||
if (curpdinfovc != null)
|
||||
rab.pdinfovc = curpdinfovc;
|
||||
// 完成绘制并保存矩形
|
||||
CircleAndInfoList.Add(rab);
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.CircleAndInfoList.Add(rab);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CircleAndInfoList.Add(rab);
|
||||
}
|
||||
|
||||
|
||||
drawCircle = false;
|
||||
if (!isContinuous)
|
||||
@ -1290,8 +1326,18 @@ namespace PBAnaly.Module
|
||||
}
|
||||
if (curpdinfovc != null)
|
||||
rattb.pdinfovc = curpdinfovc;
|
||||
|
||||
rectangles[rectDragStartIndex] = rattb;
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.rectangles[rectDragStartIndex] = rattb;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rectangles[rectDragStartIndex] = rattb;
|
||||
}
|
||||
|
||||
imagePaletteForm.SetInfo = "w:" + recDragRect.Width.ToString() + "h:" + recDragRect.Height.ToString();
|
||||
isRecDragging = false;
|
||||
rectActiveCorner = Corner.None;
|
||||
@ -1322,7 +1368,18 @@ namespace PBAnaly.Module
|
||||
}
|
||||
circeAndInfo.pdinfovc = curpdinfovc;
|
||||
imagePaletteForm.SetInfo = "radio:" + radius.ToString();
|
||||
CircleAndInfoList[cirDragStartIndex] = circeAndInfo;
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.CircleAndInfoList[cirDragStartIndex] = circeAndInfo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CircleAndInfoList[cirDragStartIndex] = circeAndInfo;
|
||||
}
|
||||
|
||||
isCirDragging = false;
|
||||
cirDragStartIndex = -1;
|
||||
imagePanel.image_pl.Invalidate();
|
||||
@ -1531,8 +1588,18 @@ namespace PBAnaly.Module
|
||||
}
|
||||
}
|
||||
curPolygonAndInfoList.pdinfovc = curpdinfovc;
|
||||
|
||||
PolygonAndInfoList.Add(curPolygonAndInfoList);
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.PolygonAndInfoList.Add(curPolygonAndInfoList);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PolygonAndInfoList.Add(curPolygonAndInfoList);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1543,16 +1610,22 @@ namespace PBAnaly.Module
|
||||
|
||||
private void Image_pl_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
|
||||
curTmpDownShape = ShapeForm.None;
|
||||
|
||||
Wdb_title_Click(null, null);
|
||||
System.Drawing.Point readLoction = ImageProcess.ConvertPictureBoxToReal( e.Location, imagePanel.image_pl);
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
{
|
||||
curTmpDownShapePoint = readLoction;
|
||||
if (IsPointInRectangles(readLoction, rectangles, out var cner, out var cr, out var index))
|
||||
{
|
||||
rectActiveCorner = cner;
|
||||
|
||||
if (rectActiveCorner != Corner.None)
|
||||
{
|
||||
curTmpDownShape = ShapeForm.Rect;
|
||||
curTmpDownShapeIndex = index;
|
||||
isRecDragging = true;
|
||||
recDragStart = readLoction;
|
||||
rectOriginalRect = cr;
|
||||
@ -1564,6 +1637,8 @@ namespace PBAnaly.Module
|
||||
rectActiveCorner = cner1;
|
||||
if (rectActiveCorner != Corner.None)
|
||||
{
|
||||
curTmpDownShape = ShapeForm.Circle;
|
||||
curTmpDownShapeIndex = index;
|
||||
isCirDragging = true;
|
||||
cirDragStart = readLoction;
|
||||
cireOriginalCire = curRect;
|
||||
@ -1633,7 +1708,8 @@ namespace PBAnaly.Module
|
||||
if (ImageProcess.IsPointOnLine(readLoction,startPoint,endPoint,CircleRadius))
|
||||
{
|
||||
curShape = ShapeForm.Line;
|
||||
|
||||
imagePanel.ctms_strop_delete.Enabled = true;
|
||||
|
||||
}
|
||||
else if (IsPointInCircle(readLoction, CircleAndInfoList, out var cner1, out var curRect, out var index1))
|
||||
{
|
||||
@ -1652,7 +1728,8 @@ namespace PBAnaly.Module
|
||||
else if (drawpolygon==false && IsPointInPolygon(readLoction, curPolygonAndInfoList))
|
||||
{
|
||||
curShape = ShapeForm.Polygon;
|
||||
|
||||
imagePanel.ctms_strop_delete.Enabled = true;
|
||||
|
||||
}
|
||||
curShapePoint = readLoction;
|
||||
}
|
||||
@ -1694,7 +1771,18 @@ namespace PBAnaly.Module
|
||||
case ShapeForm.Rect:
|
||||
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(curShapePoint, new System.Drawing.Size(oldCopyRect.rect.Width,oldCopyRect.rect.Height));
|
||||
oldCopyRect.rect = rectangle;
|
||||
rectangles.Add(oldCopyRect);
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.rectangles.Add(oldCopyRect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rectangles.Add(oldCopyRect);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case ShapeForm.Circle:
|
||||
@ -1708,10 +1796,20 @@ namespace PBAnaly.Module
|
||||
point.X += offsetX;
|
||||
point.Y += offsetY;
|
||||
oldCopyCircle.Radius = point;
|
||||
|
||||
|
||||
|
||||
CircleAndInfoList.Add(oldCopyCircle);
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.CircleAndInfoList.Add(oldCopyCircle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CircleAndInfoList.Add(oldCopyCircle);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1719,6 +1817,7 @@ namespace PBAnaly.Module
|
||||
|
||||
imagePanel.image_pl.Invalidate();
|
||||
}
|
||||
|
||||
private void Ctms_strop_delete_Click(object sender, EventArgs e)
|
||||
{
|
||||
switch (curShape)
|
||||
@ -1726,24 +1825,75 @@ namespace PBAnaly.Module
|
||||
case ShapeForm.None:
|
||||
break;
|
||||
case ShapeForm.Line:
|
||||
startPoint = new System.Drawing.Point(-10, 0);
|
||||
endPoint = new System.Drawing.Point(-10, 0);
|
||||
imagePanel.image_pl.Invalidate();
|
||||
imagePaletteForm.flb_act_mm.Text = ("0");
|
||||
imagePaletteForm.flb_act_mm.Refresh();
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.startPoint = new System.Drawing.Point(-10, 0);
|
||||
item.Value.endPoint = new System.Drawing.Point(-10, 0);
|
||||
item.Value.imagePanel.image_pl.Invalidate();
|
||||
item.Value.imagePaletteForm.flb_act_mm.Text = ("0");
|
||||
item.Value.imagePaletteForm.flb_act_mm.Refresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
startPoint = new System.Drawing.Point(-10, 0);
|
||||
endPoint = new System.Drawing.Point(-10, 0);
|
||||
imagePanel.image_pl.Invalidate();
|
||||
imagePaletteForm.flb_act_mm.Text = ("0");
|
||||
imagePaletteForm.flb_act_mm.Refresh();
|
||||
}
|
||||
|
||||
break;
|
||||
case ShapeForm.Polygon:
|
||||
PolygonAndInfoList.Clear();
|
||||
curPolygonAndInfoList.points.Clear();
|
||||
curPolygonAndInfoList.pdinfovc = null;
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.PolygonAndInfoList.Clear();
|
||||
if(item.Value.curPolygonAndInfoList.points!=null)
|
||||
item.Value.curPolygonAndInfoList.points.Clear();
|
||||
item.Value.curPolygonAndInfoList.pdinfovc = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PolygonAndInfoList.Clear();
|
||||
curPolygonAndInfoList.points.Clear();
|
||||
curPolygonAndInfoList.pdinfovc = null;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case ShapeForm.Rect:
|
||||
rectangles.RemoveAt(curShapeIndex);
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.rectangles.RemoveAt(curShapeIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rectangles.RemoveAt(curShapeIndex);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case ShapeForm.Circle:
|
||||
CircleAndInfoList.RemoveAt(curShapeIndex);
|
||||
if (Arrangement == 2)
|
||||
{
|
||||
foreach (var item in bioanalysisMannages)
|
||||
{
|
||||
item.Value.CircleAndInfoList.RemoveAt(curShapeIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CircleAndInfoList.RemoveAt(curShapeIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
break;
|
||||
@ -1754,11 +1904,32 @@ namespace PBAnaly.Module
|
||||
imagePanel.image_pl.Invalidate();
|
||||
}
|
||||
|
||||
private void OnKeyPressed(Keys key, bool ctrl, bool shift, bool alt)
|
||||
{
|
||||
if (IsActive == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctrl && key == Keys.C)
|
||||
{
|
||||
curShape = curTmpDownShape;
|
||||
curTmpDownShapeIndex = curShapeIndex;
|
||||
// 复制矩形 目前只允许复制矩形和圆形
|
||||
Ctms_strop_copy_Click(null, null);
|
||||
}
|
||||
|
||||
if (ctrl && key == Keys.V)
|
||||
{
|
||||
curShapePoint = curTmpDownShapePoint;
|
||||
Ctms_strop_stickup_Click(null, null);
|
||||
}
|
||||
}
|
||||
private void ImagePanel_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (this.imagePaletteForm != null)
|
||||
{
|
||||
KeyboardListener.Unregister(OnKeyPressed);
|
||||
this.imagePaletteForm.Close();
|
||||
this.imagePaletteForm.Dispose();
|
||||
this.imagePaletteForm = null;
|
||||
|
133
src/PBAnaly/Module/KeyboardListener.cs
Normal file
133
src/PBAnaly/Module/KeyboardListener.cs
Normal file
@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PBAnaly.Module
|
||||
{
|
||||
public class KeyboardListener
|
||||
{
|
||||
private static IntPtr _hookID = IntPtr.Zero; // 全局钩子句柄
|
||||
private static LowLevelKeyboardProc _hookCallback; // 静态字段保存委托,防止GC回收
|
||||
private static readonly List<Action<Keys, bool, bool, bool>> Callbacks = new List<Action<Keys, bool, bool, bool>>(); // 存储所有注册的回调函数
|
||||
private static readonly object _lock = new object(); // 确保线程安全
|
||||
private static int _refCount = 0; // 引用计数,管理钩子的注册和释放
|
||||
|
||||
private KeyboardListener() { }
|
||||
|
||||
/// <summary>
|
||||
/// 注册一个键盘监听回调
|
||||
/// </summary>
|
||||
/// <param name="callback">键盘回调函数</param>
|
||||
public static void Register(Action<Keys, bool, bool, bool> callback)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
// 添加回调到列表
|
||||
Callbacks.Add(callback);
|
||||
|
||||
// 如果钩子还未设置,则设置钩子
|
||||
if (_refCount == 0)
|
||||
{
|
||||
_hookCallback = HookCallback; // 保存回调防止GC回收
|
||||
_hookID = SetHook(_hookCallback);
|
||||
}
|
||||
|
||||
// 增加引用计数
|
||||
_refCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销一个键盘监听回调
|
||||
/// </summary>
|
||||
/// <param name="callback">键盘回调函数</param>
|
||||
public static void Unregister(Action<Keys, bool, bool, bool> callback)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
// 移除回调
|
||||
Callbacks.Remove(callback);
|
||||
|
||||
// 减少引用计数
|
||||
_refCount--;
|
||||
|
||||
// 如果没有回调需要监听,释放钩子
|
||||
if (_refCount == 0)
|
||||
{
|
||||
UnhookWindowsHookEx(_hookID);
|
||||
_hookID = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IntPtr SetHook(LowLevelKeyboardProc proc)
|
||||
{
|
||||
using (Process curProcess = Process.GetCurrentProcess())
|
||||
using (ProcessModule curModule = curProcess.MainModule)
|
||||
{
|
||||
IntPtr hook = SetWindowsHookEx(WH_KEYBOARD_LL, proc,
|
||||
GetModuleHandle(curModule.ModuleName), 0);
|
||||
|
||||
if (hook == IntPtr.Zero)
|
||||
{
|
||||
int errorCode = Marshal.GetLastWin32Error();
|
||||
throw new SystemException($"设置全局键盘钩子失败,错误代码: {errorCode}");
|
||||
}
|
||||
|
||||
return hook;
|
||||
}
|
||||
}
|
||||
|
||||
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
|
||||
{
|
||||
int vkCode = Marshal.ReadInt32(lParam);
|
||||
Keys key = (Keys)vkCode;
|
||||
|
||||
// 检测修饰键状态
|
||||
bool ctrl = Control.ModifierKeys.HasFlag(Keys.Control);
|
||||
bool shift = Control.ModifierKeys.HasFlag(Keys.Shift);
|
||||
bool alt = Control.ModifierKeys.HasFlag(Keys.Alt);
|
||||
|
||||
// 调用所有注册的回调函数
|
||||
lock (_lock)
|
||||
{
|
||||
foreach (var callback in Callbacks)
|
||||
{
|
||||
callback?.Invoke(key, ctrl, shift, alt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookEx(_hookID, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
#region Windows API
|
||||
|
||||
private const int WH_KEYBOARD_LL = 13; // 全局键盘钩子
|
||||
private const int WM_KEYDOWN = 0x0100; // 键盘按下消息
|
||||
|
||||
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -112,7 +112,18 @@ namespace PBAnaly.Module
|
||||
|
||||
return pixels;
|
||||
}
|
||||
public static ushort[] ConvertL16ImageToUShortArray(Image<L16> image)
|
||||
{
|
||||
var byteArray = ConvertL16ImageToByteArray(image);
|
||||
ushort[] ushortArray = new ushort[byteArray.Length / 2];
|
||||
for (int i = 0; i < byteArray.Length; i += 2)
|
||||
{
|
||||
// 使用BitConverter来确保字节正确地转换为ushort
|
||||
ushortArray[i / 2] = BitConverter.ToUInt16(byteArray, i);
|
||||
}
|
||||
|
||||
return ushortArray;
|
||||
}
|
||||
public static Bitmap ConvertL16ToBitmap(Image<L16> image)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
|
@ -89,6 +89,7 @@
|
||||
</Compile>
|
||||
<Compile Include="Module\BioanalysisMannage.cs" />
|
||||
<Compile Include="Module\ImageProcess.cs" />
|
||||
<Compile Include="Module\KeyboardListener.cs" />
|
||||
<Compile Include="Module\PBAnalyCommMannager.cs" />
|
||||
<Compile Include="Module\util.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
@ -215,6 +216,9 @@
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Activiz.NET.x64">
|
||||
<Version>5.8.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="AntdUI">
|
||||
<Version>1.6.14</Version>
|
||||
</PackageReference>
|
||||
@ -260,6 +264,9 @@
|
||||
<PackageReference Include="ScottPlot.WinForms">
|
||||
<Version>5.0.43</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SharpDX.D3DCompiler">
|
||||
<Version>4.2.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SixLabors.ImageSharp">
|
||||
<Version>2.1.9</Version>
|
||||
</PackageReference>
|
||||
|
@ -3,6 +3,7 @@ using System.Threading;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using PBAnaly.Module;
|
||||
using PBAnaly.UI;
|
||||
namespace PBAnaly
|
||||
{
|
||||
public static class Global
|
||||
|
31
src/PBAnaly/UI/BioanalyImagePanel.Designer.cs
generated
31
src/PBAnaly/UI/BioanalyImagePanel.Designer.cs
generated
@ -263,13 +263,14 @@
|
||||
//
|
||||
// tlp_bottom_panel
|
||||
//
|
||||
this.tlp_bottom_panel.ColumnCount = 4;
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 97F));
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 120F));
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tlp_bottom_panel.ColumnCount = 5;
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1F));
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1F));
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1F));
|
||||
this.tlp_bottom_panel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1F));
|
||||
this.tlp_bottom_panel.Controls.Add(this.lb_name, 0, 0);
|
||||
this.tlp_bottom_panel.Controls.Add(this.lb_size, 1, 0);
|
||||
this.tlp_bottom_panel.Controls.Add(this.lb_size, 4, 0);
|
||||
this.tlp_bottom_panel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlp_bottom_panel.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlp_bottom_panel.Name = "tlp_bottom_panel";
|
||||
@ -286,7 +287,7 @@
|
||||
this.lb_name.Location = new System.Drawing.Point(0, 0);
|
||||
this.lb_name.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lb_name.Name = "lb_name";
|
||||
this.lb_name.Size = new System.Drawing.Size(97, 13);
|
||||
this.lb_name.Size = new System.Drawing.Size(348, 13);
|
||||
this.lb_name.TabIndex = 1;
|
||||
this.lb_name.Text = "800x600";
|
||||
//
|
||||
@ -295,13 +296,14 @@
|
||||
this.lb_size.BackColor = System.Drawing.Color.Transparent;
|
||||
this.lb_size.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lb_size.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(237)))), ((int)(((byte)(237)))), ((int)(((byte)(237)))));
|
||||
this.lb_size.Location = new System.Drawing.Point(97, 0);
|
||||
this.lb_size.Location = new System.Drawing.Point(351, 0);
|
||||
this.lb_size.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lb_size.Name = "lb_size";
|
||||
this.lb_size.Size = new System.Drawing.Size(120, 13);
|
||||
this.lb_size.Size = new System.Drawing.Size(1, 13);
|
||||
this.lb_size.TabIndex = 0;
|
||||
this.lb_size.Text = "800x600";
|
||||
this.lb_size.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
this.lb_size.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.lb_size.Visible = false;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
@ -321,11 +323,18 @@
|
||||
//
|
||||
// pl_panel_image
|
||||
//
|
||||
this.pl_panel_image.Back = System.Drawing.Color.FromArgb(((int)(((byte)(6)))), ((int)(((byte)(6)))), ((int)(((byte)(6)))));
|
||||
this.pl_panel_image.Back = System.Drawing.Color.FromArgb(((int)(((byte)(69)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.pl_panel_image.Badge = "";
|
||||
this.pl_panel_image.BadgeOffsetX = 0;
|
||||
this.pl_panel_image.BadgeOffsetY = 200;
|
||||
this.pl_panel_image.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(245)))), ((int)(((byte)(26)))), ((int)(((byte)(111)))));
|
||||
this.pl_panel_image.BorderStyle = System.Drawing.Drawing2D.DashStyle.Custom;
|
||||
this.pl_panel_image.BorderWidth = 5F;
|
||||
this.pl_panel_image.Controls.Add(this.pl_bg_panel);
|
||||
this.pl_panel_image.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pl_panel_image.Location = new System.Drawing.Point(3, 3);
|
||||
this.pl_panel_image.Name = "pl_panel_image";
|
||||
this.pl_panel_image.Padding = new System.Windows.Forms.Padding(5);
|
||||
this.pl_panel_image.Size = new System.Drawing.Size(280, 237);
|
||||
this.pl_panel_image.TabIndex = 0;
|
||||
this.pl_panel_image.Text = "panel4";
|
||||
|
@ -43,11 +43,11 @@ namespace PBAnaly.UI
|
||||
pl_bg_panel.Width = pl_panel_image.Width;
|
||||
pl_bg_panel.Height = pl_panel_image.Height;
|
||||
CenterPictureBox();
|
||||
|
||||
|
||||
image_pl.MouseWheel += Image_pl_MouseWheel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region 对外方法
|
||||
public void SetButtomLabel(string value)
|
||||
@ -176,10 +176,10 @@ namespace PBAnaly.UI
|
||||
#region 事件
|
||||
public void ava_auto_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
pl_panel_image.Back = System.Drawing.Color.Gray;
|
||||
pl_bg_panel.Location = new System.Drawing.Point(pl_panel_image.Location.X, pl_panel_image.Location.Y);
|
||||
pl_bg_panel.Width = pl_panel_image.Width;
|
||||
pl_bg_panel.Height = pl_panel_image.Height;
|
||||
pl_bg_panel.Width = pl_panel_image.Width - 10;
|
||||
pl_bg_panel.Height = pl_panel_image.Height -10;
|
||||
CenterPictureBox();
|
||||
}
|
||||
private void ava__zoom_in_Click(object sender, EventArgs e)
|
||||
@ -263,10 +263,10 @@ namespace PBAnaly.UI
|
||||
currentZoom *= factor;
|
||||
int w = (int)(pl_bg_panel.Width * factor);
|
||||
int h = (int)(pl_bg_panel.Height * factor);
|
||||
if (w < pl_panel_image.Width || h < pl_panel_image.Height)
|
||||
if (w < pl_panel_image.Width - 50 || h < pl_panel_image.Height - 50)
|
||||
{
|
||||
w = pl_panel_image.Width;
|
||||
h = pl_panel_image.Height;
|
||||
w = pl_panel_image.Width - 50;
|
||||
h = pl_panel_image.Height - 50;
|
||||
}
|
||||
|
||||
if (w > pl_panel_image.Width * 5 || h > pl_panel_image.Height * 5)
|
||||
|
Loading…
Reference in New Issue
Block a user