Skip to content

Commit

Permalink
持续改进各种功能
Browse files Browse the repository at this point in the history
  • Loading branch information
DigitalPlatform committed Jan 16, 2024
1 parent fa3fe4c commit 38ea942
Show file tree
Hide file tree
Showing 61 changed files with 1,880 additions and 452 deletions.
89 changes: 77 additions & 12 deletions DigitalPlatform.IO/BarcodeCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,36 @@
using System.Threading.Tasks;
using System.Windows.Forms;

// https://www.codeproject.com/articles/14485/low-level-windows-api-hooks-from-c-to-stop-unwante

namespace DigitalPlatform.IO
{
/// <summary>
/// 捕捉条码输入
/// </summary>
public class BarcodeCapture
{
// 禁用的键
List<Keys> _stopKeys = new List<Keys>();
public IEnumerable<Keys> StopKeys
{
get
{
return new List<Keys>(_stopKeys);
}
set
{
if (value == null)
_stopKeys = new List<Keys>();
else
_stopKeys = new List<Keys>(value);
}
}

// 是否临时暂停对扫入条码的监控。
// 监控状态下会触发 InputLine 和 InputChar 事件,暂停了就不会触发了
public bool PauseBarcodeMonitor { get; set; }

public delegate void Delegate_lineFeed(StringInput input);
public event Delegate_lineFeed InputLine;

Expand Down Expand Up @@ -115,46 +138,77 @@ private struct EventMsg

StringInput _string = new StringInput();

static int TIME_SHTRESHOLD = 50;
static int TIME_SHRESHOLD = 50;

private const int WM_KEYDOWN = 0x0100;
private const int WM_KEYUP = 0x0101;
private const int WM_SYSKEYDOWN = 0x0104; // https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-syskeydown
private const int WM_SYSKEYUP = 0x0105;

static bool _shift = false;
static bool _alt = false;

private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
bool is_stop_key = false;

if (nCode == 0)
{
EventMsg msg = (EventMsg)Marshal.PtrToStructure(lParam, typeof(EventMsg));
if (wParam == WM_KEYUP)
int vkCode = Marshal.ReadInt32(lParam);
Keys key = (Keys)vkCode;
if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
{
int vkCode = Marshal.ReadInt32(lParam);

Keys key = (Keys)vkCode;

if (key == Keys.LShiftKey)
{
_shift = false;
goto END1;
}

if (key == Keys.LMenu || key == Keys.RMenu)
{
_alt = false;
Debug.WriteLine("Alt keyup");
goto END1;
}

// 检查是否属于禁用的键
is_stop_key = IsStopKey(key);
}

if (wParam == WM_KEYDOWN)//WM_KEYDOWN=0x100
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)//WM_KEYDOWN=0x100
{
/*
int vkCode = Marshal.ReadInt32(lParam);
Keys key = (Keys)vkCode;

*/
if (key == Keys.LShiftKey)
{
_shift = true;
// Console.WriteLine($"modi {(System.Windows.Forms.Keys)vkCode}");
goto END1;
}

if (key == Keys.LMenu || key == Keys.RMenu)
{
_alt = true;
Debug.WriteLine("Alt keydown");
goto END1;
}

// 检查是否属于禁用的键
is_stop_key = IsStopKey(key);

if (wParam == WM_SYSKEYDOWN)
goto END1;

// 2024/1/10
if (this.PauseBarcodeMonitor)
goto END1;

TimeSpan ts = DateTime.Now.Subtract(_string.Time);
if (ts.TotalMilliseconds > TIME_SHTRESHOLD)
if (ts.TotalMilliseconds > TIME_SHRESHOLD)
_barcode.Clear();

_string.Time = DateTime.Now;
Expand Down Expand Up @@ -195,7 +249,7 @@ private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
}
}

if ((msg.message & 0xff) == 13 && _barcode.Length > 3)
if ((msg.message & 0xff) == 13 /*&& _barcode.Length > 3*/)
{
// 回车
_string.Barcode = _barcode.ToString();// barCode.OriginalBarCode;
Expand Down Expand Up @@ -247,7 +301,8 @@ private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
}
}
END1:
if (Handled == true)
if (Handled == true
|| is_stop_key)
{
/*
if (wParam == WM_KEYDOWN)
Expand All @@ -258,6 +313,17 @@ private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}

// 检查是否属于禁用的键
public bool IsStopKey(Keys key)
{
Debug.WriteLine("IsStopKey() key=" + key.ToString());

if (_alt)
key |= Keys.Alt;

return _stopKeys.Where(o => o == key).Any();
}

/*
static char[] upper_number = new char[] { ')','!','@',
'#','$','%','^','&','*','(',
Expand Down Expand Up @@ -346,7 +412,6 @@ public static string GetKeyString(Keys key, bool shift)
if (def == null)
return "?";
return char.ToString(def[shift ? 1 : 0]);

}
else if (key == Keys.Return)
{
Expand Down
22 changes: 22 additions & 0 deletions DigitalPlatform.LibraryServer/AppDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8420,9 +8420,31 @@ int RefreshDatabase(RmsChannel channel,
}
}

static bool IsXml(string xml)
{
if (string.IsNullOrEmpty(xml))
return false;
if (xml.StartsWith("<") == false)
return false;
XmlDocument dom = new XmlDocument();
try
{
dom.LoadXml(xml);
return true;
}
catch
{
return false;
}
}

// 比较两个 XML 字符串是否等同
static bool IsSame(string xml1, string xml2)
{
// 先判断两个文件是否都是 XML 格式
if (IsXml(xml1) == false || IsXml(xml2) == false)
return string.Equals(xml1, xml2);

return DomUtil.GetIndentXml(xml1) == DomUtil.GetIndentXml(xml2);
// return XNode.DeepEquals(XElement.Parse(xml1), XElement.Parse(xml2));
}
Expand Down
5 changes: 3 additions & 2 deletions DigitalPlatform.LibraryServer/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("3.153.*")]
[assembly: AssemblyFileVersion("3.153.0.0")]
[assembly: AssemblyVersion("3.154.*")]
[assembly: AssemblyFileVersion("3.154.0.0")]

// 2.1 (2012/4/5) 第一个具有版本号的版本。特点是增加了改造了GetIssueInfo() GetOrderInfo() GetCoomentInfo() 修改了第一参数名,去掉了第二参数
// 2.11 (2012/5/5) 为ListBiblioDbFroms() API增加了 item order issue 几个类型
Expand Down Expand Up @@ -381,3 +381,4 @@ public bool ItemCanReturn(Account account,
// 3.151 (2023/11/27) Return() API 的验证还书对于提交证号的会出现报错,这个 bug 已经修正。
// 3.152 (2023/12/14) GetItemInfo() API 中的书目格式增加了 coverImageUrl:MediumImage 格式。用于获得书目记录的封面图像 856$u
// 3.153 (2023/12/15) 修正 Return() API 在验证还书时的一个 bug
// 3.154 (2024/1/16) 修正 ManageDatabase() API 中刷新书目库配置文件功能中的一个比对非 XML 字符串的 bug
1 change: 1 addition & 0 deletions DigitalPlatform/4.0/Stop/Looping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public Looping(

Progress = new Stop();
// Progress.Register(this.Host.StopManager/*_stopManager*/, activate); // 和容器关联
// TODO: 注意此处尚未 .Activate()
Progress.Register(this.Host.StopManager, groupName);

_handler = handler;
Expand Down
17 changes: 13 additions & 4 deletions DigitalPlatform/4.0/Stop/NewStop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,19 @@ public void SetProgressValue(long lValue, object tag = null)
// 注:只有当所属的 group 是 active group 时,才会作用到显示
public bool MoveToTop()
{
if (this.Group == null)
return false;
return this.Group.MoveToTop(this);
// 注意本函数的效果是不完满的,建议用 StopManager.Activate(Stop stop) 处理
// 2024/1/9 增加锁定语句
this.m_stoplock.AcquireReaderLock(Stop.m_nLockTimeout);
try
{
if (this.Group == null)
return false;
return this.Group.MoveToTop(this);
// 注意本函数的效果是不完满的,建议用 StopManager.Activate(Stop stop) 处理
}
finally
{
this.m_stoplock.ReleaseReaderLock();
}
}

public void HideProgress()
Expand Down
8 changes: 8 additions & 0 deletions UnitTestGeneral/UnitTestGeneral.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,22 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="UnitTestNewStop.cs" />
<Compile Include="UnitTestScript.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalPlatform\4.0\DigitalPlatform.csproj">
<Project>{BDD43275-EAA0-4670-8BA3-0DB5CD7598DD}</Project>
<Name>DigitalPlatform</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
Expand Down
120 changes: 120 additions & 0 deletions UnitTestGeneral/UnitTestNewStop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using DigitalPlatform;

namespace UnitTestGeneral
{
// 测试 NewStop 相关类
[TestClass]
public class UnitTestNewStop
{
// 最简单的情况:一个线程
[TestMethod]
public void Test_newStop_01()
{
LoopingHost host = new LoopingHost();
host.StopManager = new StopManager { OwnerControl = new System.Windows.Forms.TextBox() };
host.StopManager.CreateGroup("test");
host.GroupName = "test";

var looping = host.BeginLoop(
(s, e) => { },
"text",
"");
try
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(10);
}
}
finally
{
looping.Dispose();
}

}

// 两个线程
[TestMethod]
public void Test_newStop_02()
{
LoopingHost host = new LoopingHost();
host.StopManager = new StopManager { OwnerControl = new System.Windows.Forms.TextBox() };
host.StopManager.CreateGroup("test");
host.GroupName = "test";

var loopings = new List<Looping>();

var task1 = Task.Run(() =>
{
var looping = host.BeginLoop(
(s, e) => { },
"text1",
"");
loopings.Add(looping);
try
{
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(10);
}
}
finally
{
looping.Dispose();
}

});

var task2 = Task.Run(() =>
{
var looping = host.BeginLoop(
(s, e) => { },
"text2",
"");
loopings.Add(looping);
try
{
for (int i = 0; i < 500; i++)
{
Thread.Sleep(10);
}
}
finally
{
looping.Dispose();
}

});

bool finish = false;
// 反复 Activate()
var task3 = Task.Run(() =>
{
while(loopings.Count < 2)
{
Thread.Sleep(0);
}
foreach (var looping in loopings)
{
if (finish == true)
break;
host.StopManager.Activate(looping.Progress);
Thread.Sleep(0);
}
});

Task.WaitAll(task1, task2);
finish = true;
}

}
}
Loading

0 comments on commit 38ea942

Please sign in to comment.