mirror of
https://github.com/soukoku/ntwain.git
synced 2025-11-24 08:47:06 +08:00
Started on scan event handling.
This commit is contained in:
26
LICENSE.txt
26
LICENSE.txt
@@ -1,30 +1,7 @@
|
||||
NTWAIN
|
||||
-------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012 - 2021 Eugene Wang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
===============================================================================
|
||||
|
||||
TwainWorkingGroup.TWAIN
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright(C) 2013 - 2020 Kodak Alaris Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -44,4 +21,3 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
===============================================================================
|
||||
|
||||
@@ -24,10 +24,15 @@ namespace NTwain
|
||||
{
|
||||
var info = FileVersionInfo.GetVersionInfo(application.Location);
|
||||
|
||||
_twain = new TWAIN(info.CompanyName, info.ProductName, info.ProductName,
|
||||
_twain = new TWAIN(
|
||||
info.CompanyName, info.ProductName, info.ProductName,
|
||||
(ushort)TWON_PROTOCOL.MAJOR, (ushort)TWON_PROTOCOL.MINOR,
|
||||
(uint)(DG.APP2 | DG.IMAGE),
|
||||
country, "", language, 2, 4, false, true, HandleDeviceEvent, HandleScanEvent, HandleUIThreadAction, hWnd);
|
||||
(uint)(DG.APP2 | DG.IMAGE),
|
||||
country, "", language, 2, 4, false, true,
|
||||
HandleDeviceEvent,
|
||||
HandleScanEvent,
|
||||
HandleUIThreadAction,
|
||||
hWnd);
|
||||
|
||||
_threadMarshaller = threadMarshaller ?? new ThreadPoolMarshaller();
|
||||
_hWnd = hWnd;
|
||||
@@ -45,6 +50,7 @@ namespace NTwain
|
||||
_twain.Dispose();
|
||||
_twain = null;
|
||||
}
|
||||
Log.Close();
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
@@ -52,37 +58,33 @@ namespace NTwain
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the low-level twain object.
|
||||
/// Only use if you know what you're doing.
|
||||
/// </summary>
|
||||
public TWAIN TWAIN { get { return _twain; } }
|
||||
|
||||
#region event callbacks
|
||||
|
||||
/// <summary>
|
||||
/// Raised when data source has encountered some hardwar event.
|
||||
/// </summary>
|
||||
public event EventHandler<TW_DEVICEEVENT> DeviceEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when data source comes down to state 4 from higher.
|
||||
/// </summary>
|
||||
public event EventHandler SourceDisabled;
|
||||
|
||||
private void HandleUIThreadAction(Action action)
|
||||
{
|
||||
_threadMarshaller.Invoke(action);
|
||||
}
|
||||
|
||||
private STS HandleScanEvent(bool a_blClosing)
|
||||
{
|
||||
_threadMarshaller.BeginInvoke(new Action<bool>(RaiseScanEvent), a_blClosing);
|
||||
return STS.SUCCESS;
|
||||
}
|
||||
void RaiseScanEvent(bool closing)
|
||||
{
|
||||
OnScanEvent(closing);
|
||||
ScanEvent?.Invoke(this, closing);
|
||||
}
|
||||
|
||||
protected virtual void OnScanEvent(bool closing) { }
|
||||
public event EventHandler<bool> ScanEvent;
|
||||
|
||||
private STS HandleDeviceEvent()
|
||||
{
|
||||
STS sts;
|
||||
@@ -100,7 +102,11 @@ namespace NTwain
|
||||
}
|
||||
else
|
||||
{
|
||||
RaiseDeviceEvent(twdeviceevent);
|
||||
try
|
||||
{
|
||||
DeviceEvent?.Invoke(this, twdeviceevent);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,15 +114,86 @@ namespace NTwain
|
||||
return STS.SUCCESS;
|
||||
}
|
||||
|
||||
void RaiseDeviceEvent(TW_DEVICEEVENT twdeviceevent)
|
||||
private STS HandleScanEvent(bool closing)
|
||||
{
|
||||
OnDeviceEvent(twdeviceevent);
|
||||
DeviceEvent?.Invoke(this, twdeviceevent);
|
||||
// the scan event needs to return asap since it can come from msg loop
|
||||
// so fire off the handling work to another thread
|
||||
_threadMarshaller.BeginInvoke(new Func<bool, STS>(HandleScanEventReal), closing);
|
||||
return STS.SUCCESS;
|
||||
}
|
||||
|
||||
protected virtual void OnDeviceEvent(TW_DEVICEEVENT twdeviceevent) { }
|
||||
// tracks transfer state
|
||||
bool _xferReadySent;
|
||||
bool _disableDsSent;
|
||||
|
||||
public event EventHandler<TW_DEVICEEVENT> DeviceEvent;
|
||||
void HandleScanEventReal(bool closing)
|
||||
{
|
||||
//// Scoot...
|
||||
//if (_twain == null) return STS.FAILURE;
|
||||
|
||||
//// We're superfluous...
|
||||
//if (_twain.GetState() <= STATE.S4 || closing) return STS.SUCCESS;
|
||||
|
||||
//// Handle DAT_NULL/MSG_XFERREADY...
|
||||
//if (_twain.IsMsgXferReady() && !_xferReadySent)
|
||||
//{
|
||||
// _xferReadySent = true;
|
||||
|
||||
// // Get the amount of memory needed...
|
||||
// TW_SETUPMEMXFER m_twsetupmemxfer = default;
|
||||
// var sts = _twain.DatSetupmemxfer(DG.CONTROL, MSG.GET, ref m_twsetupmemxfer);
|
||||
// if ((sts != STS.SUCCESS) || (m_twsetupmemxfer.Preferred == 0))
|
||||
// {
|
||||
// _xferReadySent = false;
|
||||
// if (!_disableDsSent)
|
||||
// {
|
||||
// _disableDsSent = true;
|
||||
// StepDown(STATE.S4);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Allocate the transfer memory (with a little extra to protect ourselves)...
|
||||
// var m_intptrXfer = Marshal.AllocHGlobal((int)m_twsetupmemxfer.Preferred + 65536);
|
||||
// if (m_intptrXfer == IntPtr.Zero)
|
||||
// {
|
||||
// _disableDsSent = true;
|
||||
// StepDown(STATE.S4);
|
||||
// }
|
||||
//}
|
||||
|
||||
//// Handle DAT_NULL/MSG_CLOSEDSREQ...
|
||||
//if (_twain.IsMsgCloseDsReq() && !_disableDsSent)
|
||||
//{
|
||||
// _disableDsSent = true;
|
||||
// StepDown(STATE.S4);
|
||||
//}
|
||||
|
||||
//// Handle DAT_NULL/MSG_CLOSEDSOK...
|
||||
//if (_twain.IsMsgCloseDsOk() && !_disableDsSent)
|
||||
//{
|
||||
// _disableDsSent = true;
|
||||
// StepDown(STATE.S4);
|
||||
//}
|
||||
|
||||
//// This is where the statemachine runs that transfers and optionally
|
||||
//// saves the images to disk (it also displays them). It'll go back
|
||||
//// and forth between states 6 and 7 until an error occurs, or until
|
||||
//// we run out of images...
|
||||
//if (_xferReadySent && !_disableDsSent)
|
||||
//{
|
||||
// CaptureImages();
|
||||
//}
|
||||
|
||||
//// Trigger the next event, this is where things all chain together.
|
||||
//// We need begininvoke to prevent blockking, so that we don't get
|
||||
//// backed up into a messy kind of recursion. We need DoEvents,
|
||||
//// because if things really start moving fast it's really hard for
|
||||
//// application events, like button clicks to break through...
|
||||
//HandleScanEvent(_twain.GetState() <= STATE.S3);
|
||||
}
|
||||
|
||||
//protected virtual void OnScanEvent(bool closing) { }
|
||||
//public event EventHandler<bool> ScanEvent;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -255,6 +332,7 @@ namespace NTwain
|
||||
{
|
||||
TW_USERINTERFACE twuserinterface = default;
|
||||
_twain.DatUserinterface(DG.CONTROL, MSG.DISABLEDS, ref twuserinterface);
|
||||
SourceDisabled?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
// 4 --> 3
|
||||
|
||||
Reference in New Issue
Block a user