mirror of
https://github.com/soukoku/ntwain.git
synced 2026-01-26 21:48:36 +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)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2012 - 2021 Eugene Wang
|
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.
|
Copyright(C) 2013 - 2020 Kodak Alaris Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
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
|
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
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
===============================================================================
|
|
||||||
|
|||||||
@@ -24,10 +24,15 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
var info = FileVersionInfo.GetVersionInfo(application.Location);
|
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,
|
(ushort)TWON_PROTOCOL.MAJOR, (ushort)TWON_PROTOCOL.MINOR,
|
||||||
(uint)(DG.APP2 | DG.IMAGE),
|
(uint)(DG.APP2 | DG.IMAGE),
|
||||||
country, "", language, 2, 4, false, true, HandleDeviceEvent, HandleScanEvent, HandleUIThreadAction, hWnd);
|
country, "", language, 2, 4, false, true,
|
||||||
|
HandleDeviceEvent,
|
||||||
|
HandleScanEvent,
|
||||||
|
HandleUIThreadAction,
|
||||||
|
hWnd);
|
||||||
|
|
||||||
_threadMarshaller = threadMarshaller ?? new ThreadPoolMarshaller();
|
_threadMarshaller = threadMarshaller ?? new ThreadPoolMarshaller();
|
||||||
_hWnd = hWnd;
|
_hWnd = hWnd;
|
||||||
@@ -45,6 +50,7 @@ namespace NTwain
|
|||||||
_twain.Dispose();
|
_twain.Dispose();
|
||||||
_twain = null;
|
_twain = null;
|
||||||
}
|
}
|
||||||
|
Log.Close();
|
||||||
}
|
}
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
@@ -52,37 +58,33 @@ namespace NTwain
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
||||||
Dispose(disposing: true);
|
Dispose(disposing: true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the low-level twain object.
|
/// Gets the low-level twain object.
|
||||||
|
/// Only use if you know what you're doing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TWAIN TWAIN { get { return _twain; } }
|
public TWAIN TWAIN { get { return _twain; } }
|
||||||
|
|
||||||
#region event callbacks
|
#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)
|
private void HandleUIThreadAction(Action action)
|
||||||
{
|
{
|
||||||
_threadMarshaller.Invoke(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()
|
private STS HandleDeviceEvent()
|
||||||
{
|
{
|
||||||
STS sts;
|
STS sts;
|
||||||
@@ -100,7 +102,11 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RaiseDeviceEvent(twdeviceevent);
|
try
|
||||||
|
{
|
||||||
|
DeviceEvent?.Invoke(this, twdeviceevent);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,15 +114,86 @@ namespace NTwain
|
|||||||
return STS.SUCCESS;
|
return STS.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaiseDeviceEvent(TW_DEVICEEVENT twdeviceevent)
|
private STS HandleScanEvent(bool closing)
|
||||||
{
|
{
|
||||||
OnDeviceEvent(twdeviceevent);
|
// the scan event needs to return asap since it can come from msg loop
|
||||||
DeviceEvent?.Invoke(this, twdeviceevent);
|
// 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
|
#endregion
|
||||||
|
|
||||||
@@ -255,6 +332,7 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
TW_USERINTERFACE twuserinterface = default;
|
TW_USERINTERFACE twuserinterface = default;
|
||||||
_twain.DatUserinterface(DG.CONTROL, MSG.DISABLEDS, ref twuserinterface);
|
_twain.DatUserinterface(DG.CONTROL, MSG.DISABLEDS, ref twuserinterface);
|
||||||
|
SourceDisabled?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4 --> 3
|
// 4 --> 3
|
||||||
|
|||||||
Reference in New Issue
Block a user