1.line和多边形增加删除功能

2.多张合并时 同步移动ROI
3.多张合并时展示重构
4.增加多张合并时同时复制粘贴
5.增加快捷键复制粘贴
This commit is contained in:
moco 2024-12-13 00:09:51 +08:00
parent 38df215f45
commit f7dbb84124
9 changed files with 399 additions and 64 deletions

View File

@ -659,7 +659,7 @@
this.thunderLabel1.Name = "thunderLabel1"; this.thunderLabel1.Name = "thunderLabel1";
this.thunderLabel1.Size = new System.Drawing.Size(200, 16); this.thunderLabel1.Size = new System.Drawing.Size(200, 16);
this.thunderLabel1.TabIndex = 19; this.thunderLabel1.TabIndex = 19;
this.thunderLabel1.Text = "PBAnaly v0.1.7"; this.thunderLabel1.Text = "PBAnaly v0.1.7rc2";
// //
// MainForm // MainForm
// //

View File

@ -447,7 +447,7 @@ namespace PBAnaly
bioanalyBool = true; bioanalyBool = true;
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
item.Value.Arrangement = false; item.Value.Arrangement = 0;
item.Value.WindowAdaptive(); item.Value.WindowAdaptive();
} }
} }
@ -456,7 +456,7 @@ namespace PBAnaly
bioanalyBool = false; bioanalyBool = false;
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
item.Value.Arrangement = false; item.Value.Arrangement = 0;
item.Value.WindowNormalAdaptive(); item.Value.WindowNormalAdaptive();
} }
} }
@ -513,12 +513,13 @@ namespace PBAnaly
data_tab.ColumnCount = data_col + 1; data_tab.ColumnCount = data_col + 1;
for (int i = 0; i < data_row; i++) for (int i = 0; i < data_row; i++)
{ {
if(i % 2==0) if(i % 2==0)
data_tab.RowStyles.Add(new RowStyle(SizeType.Percent, 100f / data_row)); data_tab.RowStyles.Add(new RowStyle(SizeType.Percent, 100f / data_row));
else 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++) for (int i = 0; i < data_col; i++)
{ {
@ -534,6 +535,7 @@ namespace PBAnaly
foreach (var bname in bioanalyName) foreach (var bname in bioanalyName)
{ {
var item = bioanalysisMannages[bname]; var item = bioanalysisMannages[bname];
item.Arrangement = 1;
if (index == bioanalysisMannages.Count - 1) if (index == bioanalysisMannages.Count - 1)
{ {
pl_right.Controls.Add(item.GetBioanayImagePanel); pl_right.Controls.Add(item.GetBioanayImagePanel);
@ -545,7 +547,7 @@ namespace PBAnaly
data_right_bar.Dock = DockStyle.Fill; data_right_bar.Dock = DockStyle.Fill;
data_tab.Controls.Add(data_right_bar, data_tab.ColumnCount - 1, 0); data_tab.Controls.Add(data_right_bar, data_tab.ColumnCount - 1, 0);
data_tab.SetRowSpan(data_right_bar, data_row); data_tab.SetRowSpan(data_right_bar, data_row);
item.Arrangement = true; item.Arrangement = 2;
} }
index++; index++;
@ -571,6 +573,7 @@ namespace PBAnaly
else else
{ {
bioanalyBool = false; bioanalyBool = false;
if (data_tab == null) return;
data_tab.Controls.Clear(); data_tab.Controls.Clear();
DataProcess_panel.Controls.Clear(); DataProcess_panel.Controls.Clear();
pl_right.Controls.Clear(); pl_right.Controls.Clear();
@ -584,7 +587,7 @@ namespace PBAnaly
pl_right.Controls.Add(item.Value.GetBioanayImagePanel); pl_right.Controls.Add(item.Value.GetBioanayImagePanel);
index++; index++;
} }
item.Value.Arrangement = false; item.Value.Arrangement = 0;
DataProcess_panel.Controls.Add(item.Value.GetImagePanel); DataProcess_panel.Controls.Add(item.Value.GetImagePanel);
item.Value.Rifresh(); item.Value.Rifresh();
item.Value.GetImagePanel.BringToFront(); item.Value.GetImagePanel.BringToFront();

View File

@ -70,12 +70,16 @@ namespace PBAnaly.Module
} }
#endregion #endregion
#region #region
private ShapeForm curTmpDownShape = ShapeForm.None;// 用于快捷键 临时确认点击了那个矩形
private ShapeForm curShape = ShapeForm.None; private ShapeForm curShape = ShapeForm.None;
private int curTmpDownShapeIndex;
private int curShapeIndex; private int curShapeIndex;
private System.Drawing.Point curTmpDownShapePoint;
private System.Drawing.Point curShapePoint; private System.Drawing.Point curShapePoint;
public bool IsActive { get; set; } // 当前窗口是否在活跃状态 用来判断是否需要操作
public int ImageIndex { 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; private Dictionary<string, BioanalysisMannage> bioanalysisMannages;
public string path { get; set; } public string path { get; set; }
private string mark_path; private string mark_path;
@ -471,6 +475,7 @@ namespace PBAnaly.Module
imagePaletteForm.fb_fixSetting.Click += Fb_fixSetting_Click; imagePaletteForm.fb_fixSetting.Click += Fb_fixSetting_Click;
imagePaletteForm.cb_continuous.CheckedChanged += Cb_continuous_CheckedChanged; imagePaletteForm.cb_continuous.CheckedChanged += Cb_continuous_CheckedChanged;
KeyboardListener.Register(OnKeyPressed); // 创建键盘钩子
} }
@ -501,7 +506,7 @@ namespace PBAnaly.Module
var t = tifFiles[0].Split("\\"); var t = tifFiles[0].Split("\\");
if (t.Length > 2) 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 #region
private void Wdb_title_Click(object sender, EventArgs e) private void Wdb_title_Click(object sender, EventArgs e)
{ {
this.pl_right.Controls.Clear(); if (Arrangement == 2 || Arrangement == 0)
this.pl_right.Controls.Add(this.imagePaletteForm); {
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(); this.imagePanel.BringToFront();
} }
private void Cb_scientific_CheckedChanged(object sender, AntdUI.BoolEventArgs e) private void Cb_scientific_CheckedChanged(object sender, AntdUI.BoolEventArgs e)
@ -793,7 +807,7 @@ namespace PBAnaly.Module
} }
private void Dtb_brightness_ValueChanged() private void Dtb_brightness_ValueChanged()
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -808,7 +822,7 @@ namespace PBAnaly.Module
} }
private void Dtb_opacity_ValueChanged() private void Dtb_opacity_ValueChanged()
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -823,7 +837,7 @@ namespace PBAnaly.Module
} }
private void Nud_opacity_ValueChanged(object sender, System.EventArgs e) private void Nud_opacity_ValueChanged(object sender, System.EventArgs e)
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -839,7 +853,7 @@ namespace PBAnaly.Module
private void Nud_brightness_ValueChanged(object sender, System.EventArgs e) private void Nud_brightness_ValueChanged(object sender, System.EventArgs e)
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -854,7 +868,7 @@ namespace PBAnaly.Module
} }
private void Nud_colorMin_ValueChanged(object sender, System.EventArgs e) private void Nud_colorMin_ValueChanged(object sender, System.EventArgs e)
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -870,7 +884,7 @@ namespace PBAnaly.Module
private void Nud_colorMax_ValueChanged(object sender, System.EventArgs e) private void Nud_colorMax_ValueChanged(object sender, System.EventArgs e)
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -886,7 +900,7 @@ namespace PBAnaly.Module
private void Dtb_colorMin_ValueChanged() private void Dtb_colorMin_ValueChanged()
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -902,7 +916,7 @@ namespace PBAnaly.Module
private void Dtb_colorMax_ValueChanged() private void Dtb_colorMax_ValueChanged()
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -917,7 +931,7 @@ namespace PBAnaly.Module
} }
private void Cb_colortable_SelectedIndexChanged(object sender, System.EventArgs e) private void Cb_colortable_SelectedIndexChanged(object sender, System.EventArgs e)
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -941,7 +955,7 @@ namespace PBAnaly.Module
// 绘制直线 // 绘制直线
if ((startPoint != System.Drawing.Point.Empty && endPoint != System.Drawing.Point.Empty)) if ((startPoint != System.Drawing.Point.Empty && endPoint != System.Drawing.Point.Empty))
{ {
if (Arrangement) if (Arrangement == 2)
{ {
foreach (var item in bioanalysisMannages) foreach (var item in bioanalysisMannages)
{ {
@ -1224,7 +1238,18 @@ namespace PBAnaly.Module
rab.pdinfovc = curpdinfovc; rab.pdinfovc = curpdinfovc;
imagePaletteForm.SetInfo = "w:" + rab.rect.Width.ToString() + "h:" + rab.rect.Height.ToString(); 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; currentRectangle = null;
drawRect = false; drawRect = false;
imagePanel.image_pl.Invalidate(); imagePanel.image_pl.Invalidate();
@ -1262,7 +1287,18 @@ namespace PBAnaly.Module
if (curpdinfovc != null) if (curpdinfovc != null)
rab.pdinfovc = curpdinfovc; 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; drawCircle = false;
if (!isContinuous) if (!isContinuous)
@ -1290,8 +1326,18 @@ namespace PBAnaly.Module
} }
if (curpdinfovc != null) if (curpdinfovc != null)
rattb.pdinfovc = curpdinfovc; rattb.pdinfovc = curpdinfovc;
if (Arrangement == 2)
{
foreach (var item in bioanalysisMannages)
{
item.Value.rectangles[rectDragStartIndex] = rattb;
}
}
else
{
rectangles[rectDragStartIndex] = rattb;
}
rectangles[rectDragStartIndex] = rattb;
imagePaletteForm.SetInfo = "w:" + recDragRect.Width.ToString() + "h:" + recDragRect.Height.ToString(); imagePaletteForm.SetInfo = "w:" + recDragRect.Width.ToString() + "h:" + recDragRect.Height.ToString();
isRecDragging = false; isRecDragging = false;
rectActiveCorner = Corner.None; rectActiveCorner = Corner.None;
@ -1322,7 +1368,18 @@ namespace PBAnaly.Module
} }
circeAndInfo.pdinfovc = curpdinfovc; circeAndInfo.pdinfovc = curpdinfovc;
imagePaletteForm.SetInfo = "radio:" + radius.ToString(); 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; isCirDragging = false;
cirDragStartIndex = -1; cirDragStartIndex = -1;
imagePanel.image_pl.Invalidate(); imagePanel.image_pl.Invalidate();
@ -1531,8 +1588,18 @@ namespace PBAnaly.Module
} }
} }
curPolygonAndInfoList.pdinfovc = curpdinfovc; curPolygonAndInfoList.pdinfovc = curpdinfovc;
if (Arrangement == 2)
{
foreach (var item in bioanalysisMannages)
{
item.Value.PolygonAndInfoList.Add(curPolygonAndInfoList);
}
}
else
{
PolygonAndInfoList.Add(curPolygonAndInfoList);
}
PolygonAndInfoList.Add(curPolygonAndInfoList);
} }
@ -1543,16 +1610,22 @@ namespace PBAnaly.Module
private void Image_pl_MouseDown(object sender, MouseEventArgs e) private void Image_pl_MouseDown(object sender, MouseEventArgs e)
{ {
curTmpDownShape = ShapeForm.None;
Wdb_title_Click(null, null); Wdb_title_Click(null, null);
System.Drawing.Point readLoction = ImageProcess.ConvertPictureBoxToReal( e.Location, imagePanel.image_pl); System.Drawing.Point readLoction = ImageProcess.ConvertPictureBoxToReal( e.Location, imagePanel.image_pl);
if (e.Button == MouseButtons.Left) if (e.Button == MouseButtons.Left)
{ {
curTmpDownShapePoint = readLoction;
if (IsPointInRectangles(readLoction, rectangles, out var cner, out var cr, out var index)) if (IsPointInRectangles(readLoction, rectangles, out var cner, out var cr, out var index))
{ {
rectActiveCorner = cner; rectActiveCorner = cner;
if (rectActiveCorner != Corner.None) if (rectActiveCorner != Corner.None)
{ {
curTmpDownShape = ShapeForm.Rect;
curTmpDownShapeIndex = index;
isRecDragging = true; isRecDragging = true;
recDragStart = readLoction; recDragStart = readLoction;
rectOriginalRect = cr; rectOriginalRect = cr;
@ -1564,6 +1637,8 @@ namespace PBAnaly.Module
rectActiveCorner = cner1; rectActiveCorner = cner1;
if (rectActiveCorner != Corner.None) if (rectActiveCorner != Corner.None)
{ {
curTmpDownShape = ShapeForm.Circle;
curTmpDownShapeIndex = index;
isCirDragging = true; isCirDragging = true;
cirDragStart = readLoction; cirDragStart = readLoction;
cireOriginalCire = curRect; cireOriginalCire = curRect;
@ -1633,6 +1708,7 @@ namespace PBAnaly.Module
if (ImageProcess.IsPointOnLine(readLoction,startPoint,endPoint,CircleRadius)) if (ImageProcess.IsPointOnLine(readLoction,startPoint,endPoint,CircleRadius))
{ {
curShape = ShapeForm.Line; curShape = ShapeForm.Line;
imagePanel.ctms_strop_delete.Enabled = true;
} }
else if (IsPointInCircle(readLoction, CircleAndInfoList, out var cner1, out var curRect, out var index1)) else if (IsPointInCircle(readLoction, CircleAndInfoList, out var cner1, out var curRect, out var index1))
@ -1652,6 +1728,7 @@ namespace PBAnaly.Module
else if (drawpolygon==false && IsPointInPolygon(readLoction, curPolygonAndInfoList)) else if (drawpolygon==false && IsPointInPolygon(readLoction, curPolygonAndInfoList))
{ {
curShape = ShapeForm.Polygon; curShape = ShapeForm.Polygon;
imagePanel.ctms_strop_delete.Enabled = true;
} }
curShapePoint = readLoction; curShapePoint = readLoction;
@ -1694,7 +1771,18 @@ namespace PBAnaly.Module
case ShapeForm.Rect: case ShapeForm.Rect:
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(curShapePoint, new System.Drawing.Size(oldCopyRect.rect.Width,oldCopyRect.rect.Height)); System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(curShapePoint, new System.Drawing.Size(oldCopyRect.rect.Width,oldCopyRect.rect.Height));
oldCopyRect.rect = rectangle; oldCopyRect.rect = rectangle;
rectangles.Add(oldCopyRect); if (Arrangement == 2)
{
foreach (var item in bioanalysisMannages)
{
item.Value.rectangles.Add(oldCopyRect);
}
}
else
{
rectangles.Add(oldCopyRect);
}
break; break;
case ShapeForm.Circle: case ShapeForm.Circle:
@ -1709,9 +1797,19 @@ namespace PBAnaly.Module
point.Y += offsetY; point.Y += offsetY;
oldCopyCircle.Radius = point; oldCopyCircle.Radius = point;
if (Arrangement == 2)
{
foreach (var item in bioanalysisMannages)
{
item.Value.CircleAndInfoList.Add(oldCopyCircle);
}
}
else
{
CircleAndInfoList.Add(oldCopyCircle);
}
CircleAndInfoList.Add(oldCopyCircle);
break; break;
default: default:
break; break;
@ -1719,6 +1817,7 @@ namespace PBAnaly.Module
imagePanel.image_pl.Invalidate(); imagePanel.image_pl.Invalidate();
} }
private void Ctms_strop_delete_Click(object sender, EventArgs e) private void Ctms_strop_delete_Click(object sender, EventArgs e)
{ {
switch (curShape) switch (curShape)
@ -1726,24 +1825,75 @@ namespace PBAnaly.Module
case ShapeForm.None: case ShapeForm.None:
break; break;
case ShapeForm.Line: case ShapeForm.Line:
startPoint = new System.Drawing.Point(-10, 0); if (Arrangement == 2)
endPoint = new System.Drawing.Point(-10, 0); {
imagePanel.image_pl.Invalidate(); foreach (var item in bioanalysisMannages)
imagePaletteForm.flb_act_mm.Text = ("0"); {
imagePaletteForm.flb_act_mm.Refresh(); 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; break;
case ShapeForm.Polygon: case ShapeForm.Polygon:
PolygonAndInfoList.Clear(); if (Arrangement == 2)
curPolygonAndInfoList.points.Clear(); {
curPolygonAndInfoList.pdinfovc = null; 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; break;
case ShapeForm.Rect: case ShapeForm.Rect:
rectangles.RemoveAt(curShapeIndex); if (Arrangement == 2)
{
foreach (var item in bioanalysisMannages)
{
item.Value.rectangles.RemoveAt(curShapeIndex);
}
}
else
{
rectangles.RemoveAt(curShapeIndex);
}
break; break;
case ShapeForm.Circle: case ShapeForm.Circle:
CircleAndInfoList.RemoveAt(curShapeIndex); if (Arrangement == 2)
{
foreach (var item in bioanalysisMannages)
{
item.Value.CircleAndInfoList.RemoveAt(curShapeIndex);
}
}
else
{
CircleAndInfoList.RemoveAt(curShapeIndex);
}
break; break;
@ -1754,11 +1904,32 @@ namespace PBAnaly.Module
imagePanel.image_pl.Invalidate(); 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) private void ImagePanel_FormClosing(object sender, FormClosingEventArgs e)
{ {
if (this.imagePaletteForm != null) if (this.imagePaletteForm != null)
{ {
KeyboardListener.Unregister(OnKeyPressed);
this.imagePaletteForm.Close(); this.imagePaletteForm.Close();
this.imagePaletteForm.Dispose(); this.imagePaletteForm.Dispose();
this.imagePaletteForm = null; this.imagePaletteForm = null;

View 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
}
}

View File

@ -112,7 +112,18 @@ namespace PBAnaly.Module
return pixels; 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) public static Bitmap ConvertL16ToBitmap(Image<L16> image)
{ {
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())

View File

@ -89,6 +89,7 @@
</Compile> </Compile>
<Compile Include="Module\BioanalysisMannage.cs" /> <Compile Include="Module\BioanalysisMannage.cs" />
<Compile Include="Module\ImageProcess.cs" /> <Compile Include="Module\ImageProcess.cs" />
<Compile Include="Module\KeyboardListener.cs" />
<Compile Include="Module\PBAnalyCommMannager.cs" /> <Compile Include="Module\PBAnalyCommMannager.cs" />
<Compile Include="Module\util.cs" /> <Compile Include="Module\util.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
@ -215,6 +216,9 @@
<None Include="App.config" /> <None Include="App.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Activiz.NET.x64">
<Version>5.8.0</Version>
</PackageReference>
<PackageReference Include="AntdUI"> <PackageReference Include="AntdUI">
<Version>1.6.14</Version> <Version>1.6.14</Version>
</PackageReference> </PackageReference>
@ -260,6 +264,9 @@
<PackageReference Include="ScottPlot.WinForms"> <PackageReference Include="ScottPlot.WinForms">
<Version>5.0.43</Version> <Version>5.0.43</Version>
</PackageReference> </PackageReference>
<PackageReference Include="SharpDX.D3DCompiler">
<Version>4.2.0</Version>
</PackageReference>
<PackageReference Include="SixLabors.ImageSharp"> <PackageReference Include="SixLabors.ImageSharp">
<Version>2.1.9</Version> <Version>2.1.9</Version>
</PackageReference> </PackageReference>

View File

@ -3,6 +3,7 @@ using System.Threading;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using PBAnaly.Module; using PBAnaly.Module;
using PBAnaly.UI;
namespace PBAnaly namespace PBAnaly
{ {
public static class Global public static class Global

View File

@ -263,13 +263,14 @@
// //
// tlp_bottom_panel // tlp_bottom_panel
// //
this.tlp_bottom_panel.ColumnCount = 4; this.tlp_bottom_panel.ColumnCount = 5;
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.Percent, 100F));
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.Absolute, 1F));
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.Absolute, 1F));
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.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_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.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlp_bottom_panel.Location = new System.Drawing.Point(0, 0); this.tlp_bottom_panel.Location = new System.Drawing.Point(0, 0);
this.tlp_bottom_panel.Name = "tlp_bottom_panel"; 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.Location = new System.Drawing.Point(0, 0);
this.lb_name.Margin = new System.Windows.Forms.Padding(0); this.lb_name.Margin = new System.Windows.Forms.Padding(0);
this.lb_name.Name = "lb_name"; 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.TabIndex = 1;
this.lb_name.Text = "800x600"; this.lb_name.Text = "800x600";
// //
@ -295,13 +296,14 @@
this.lb_size.BackColor = System.Drawing.Color.Transparent; this.lb_size.BackColor = System.Drawing.Color.Transparent;
this.lb_size.Dock = System.Windows.Forms.DockStyle.Fill; 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.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.Margin = new System.Windows.Forms.Padding(0);
this.lb_size.Name = "lb_size"; 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.TabIndex = 0;
this.lb_size.Text = "800x600"; 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 // tableLayoutPanel2
// //
@ -321,11 +323,18 @@
// //
// pl_panel_image // 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.Controls.Add(this.pl_bg_panel);
this.pl_panel_image.Dock = System.Windows.Forms.DockStyle.Fill; 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.Location = new System.Drawing.Point(3, 3);
this.pl_panel_image.Name = "pl_panel_image"; 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.Size = new System.Drawing.Size(280, 237);
this.pl_panel_image.TabIndex = 0; this.pl_panel_image.TabIndex = 0;
this.pl_panel_image.Text = "panel4"; this.pl_panel_image.Text = "panel4";

View File

@ -176,10 +176,10 @@ namespace PBAnaly.UI
#region #region
public void ava_auto_Click(object sender, EventArgs e) 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.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.Width = pl_panel_image.Width - 10;
pl_bg_panel.Height = pl_panel_image.Height; pl_bg_panel.Height = pl_panel_image.Height -10;
CenterPictureBox(); CenterPictureBox();
} }
private void ava__zoom_in_Click(object sender, EventArgs e) private void ava__zoom_in_Click(object sender, EventArgs e)
@ -263,10 +263,10 @@ namespace PBAnaly.UI
currentZoom *= factor; currentZoom *= factor;
int w = (int)(pl_bg_panel.Width * factor); int w = (int)(pl_bg_panel.Width * factor);
int h = (int)(pl_bg_panel.Height * 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; w = pl_panel_image.Width - 50;
h = pl_panel_image.Height; h = pl_panel_image.Height - 50;
} }
if (w > pl_panel_image.Width * 5 || h > pl_panel_image.Height * 5) if (w > pl_panel_image.Width * 5 || h > pl_panel_image.Height * 5)