mirror of
https://github.com/soukoku/ntwain.git
synced 2026-02-25 13:04:07 +08:00
More ready event in xfer logic.
This commit is contained in:
@@ -2385,7 +2385,7 @@ namespace NTwain.Data
|
|||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
public struct TW_PENDINGXFERS
|
public struct TW_PENDINGXFERS
|
||||||
{
|
{
|
||||||
public ushort Count;
|
public short Count;
|
||||||
public uint EOJ;
|
public uint EOJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
85
src/NTwain/TransferReadyEventArgs.cs
Normal file
85
src/NTwain/TransferReadyEventArgs.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using NTwain.Data;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NTwain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains event data when a data transfer is ready to be processed.
|
||||||
|
/// </summary>
|
||||||
|
public class TransferReadyEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public TransferReadyEventArgs(TwainAppSession twain, int pendingCount, TWEJ endOfJobFlag)
|
||||||
|
{
|
||||||
|
_twain = twain;
|
||||||
|
PendingCount = pendingCount;
|
||||||
|
EndOfJobFlag = endOfJobFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether the current transfer should be skipped
|
||||||
|
/// and continue next transfer if there are more data.
|
||||||
|
/// </summary>
|
||||||
|
public bool SkipCurrent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets whether to cancel the capture phase.
|
||||||
|
/// </summary>
|
||||||
|
public CancelType Cancel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the end of job flag value for this transfer if job control is enabled.
|
||||||
|
/// </summary>
|
||||||
|
public TWEJ EndOfJobFlag { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the known pending transfer count. This may not be appilicable
|
||||||
|
/// for certain scanning modes.
|
||||||
|
/// </summary>
|
||||||
|
public int PendingCount { get; private set; }
|
||||||
|
|
||||||
|
TW_IMAGEINFO? _imgInfo;
|
||||||
|
private readonly TwainAppSession _twain;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the tentative image information for the current transfer if applicable.
|
||||||
|
/// This may differ from the final image depending on the transfer mode used (mostly when doing mem xfer).
|
||||||
|
/// </summary>
|
||||||
|
public TW_IMAGEINFO? PendingImageInfo
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// only get it if requested since it could be slow
|
||||||
|
if (!_imgInfo.HasValue)
|
||||||
|
{
|
||||||
|
if (_twain.GetImageInfo(out TW_IMAGEINFO info).RC == TWRC.SUCCESS)
|
||||||
|
{
|
||||||
|
_imgInfo = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _imgInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CancelType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No cancel.
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
/// <summary>
|
||||||
|
/// Skips current transfer.
|
||||||
|
/// </summary>
|
||||||
|
SkipCurrent,
|
||||||
|
/// <summary>
|
||||||
|
/// Stops feeder but continue receiving already scanned images in the app.
|
||||||
|
/// </summary>
|
||||||
|
Graceful,
|
||||||
|
/// <summary>
|
||||||
|
/// Stops feeder and discard any pending images.
|
||||||
|
/// </summary>
|
||||||
|
EndNow
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -140,5 +140,16 @@ namespace NTwain
|
|||||||
/// Fires when there's an error during transfer.
|
/// Fires when there's an error during transfer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<TransferErrorEventArgs>? TransferError;
|
public event EventHandler<TransferErrorEventArgs>? TransferError;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires when there's an upcoming transfer. App can inspect the image info
|
||||||
|
/// and cancel if needed.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<TransferReadyEventArgs>? TransferReady;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires when transferred data is available for app to use.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<DataTransferredEventArgs>? DataTransferred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ namespace NTwain
|
|||||||
// so the array max is made with 32 MB. Typical usage should be a lot less.
|
// so the array max is made with 32 MB. Typical usage should be a lot less.
|
||||||
static readonly ArrayPool<byte> XferMemPool = ArrayPool<byte>.Create(32505856, 4);
|
static readonly ArrayPool<byte> XferMemPool = ArrayPool<byte>.Create(32505856, 4);
|
||||||
|
|
||||||
|
public STS GetImageInfo(out TW_IMAGEINFO info)
|
||||||
|
{
|
||||||
|
return WrapInSTS(DGImage.ImageInfo.Get(ref _appIdentity, ref _currentDS, out info));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start the transfer loop.
|
/// Start the transfer loop.
|
||||||
@@ -49,14 +54,22 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (xferImage)
|
if (xferImage)
|
||||||
//{
|
{
|
||||||
// imgXferMech = session.CurrentSource.Capabilities.ICapXferMech.GetCurrent();
|
if (GetCapCurrent(CAP.ICAP_XFERMECH, out TW_CAPABILITY cap).RC == TWRC.SUCCESS)
|
||||||
//}
|
{
|
||||||
//if (xferAudio)
|
// todo:
|
||||||
//{
|
cap.Free(this);
|
||||||
// audXferMech = session.CurrentSource.Capabilities.ACapXferMech.GetCurrent();
|
}
|
||||||
//}
|
}
|
||||||
|
else if (xferAudio)
|
||||||
|
{
|
||||||
|
if (GetCapCurrent(CAP.ACAP_XFERMECH, out TW_CAPABILITY cap).RC == TWRC.SUCCESS)
|
||||||
|
{
|
||||||
|
// todo:
|
||||||
|
cap.Free(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TW_PENDINGXFERS pending = default;
|
TW_PENDINGXFERS pending = default;
|
||||||
var rc = DGControl.PendingXfers.Get(ref _appIdentity, ref _currentDS, ref pending);
|
var rc = DGControl.PendingXfers.Get(ref _appIdentity, ref _currentDS, ref pending);
|
||||||
@@ -64,20 +77,37 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// cancel for now
|
var readyArgs = new TransferReadyEventArgs(this, pending.Count, (TWEJ)pending.EOJ);
|
||||||
//rc = DGControl.PendingXfers.Reset(ref _appIdentity, ref _currentDS, ref pending);
|
_uiThreadMarshaller.Invoke(() =>
|
||||||
|
{
|
||||||
|
TransferReady?.Invoke(this, readyArgs);
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (readyArgs.Cancel)
|
||||||
|
{
|
||||||
|
case CancelType.SkipCurrent:
|
||||||
|
rc = DGControl.PendingXfers.EndXfer(ref _appIdentity, ref _currentDS, ref pending);
|
||||||
|
break;
|
||||||
|
case CancelType.EndNow:
|
||||||
|
rc = DGControl.PendingXfers.Reset(ref _appIdentity, ref _currentDS, ref pending);
|
||||||
|
break;
|
||||||
|
case CancelType.Graceful:
|
||||||
|
//??? oh boy
|
||||||
|
rc = DGControl.PendingXfers.EndXfer(ref _appIdentity, ref _currentDS, ref pending);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// normal capture
|
||||||
|
if (xferImage)
|
||||||
|
{
|
||||||
|
|
||||||
rc = DGControl.PendingXfers.EndXfer(ref _appIdentity, ref _currentDS, ref pending);
|
}
|
||||||
|
else if (xferAudio)
|
||||||
|
{
|
||||||
|
|
||||||
//if (xferType.HasFlag(DG.AUDIO))
|
}
|
||||||
//{
|
rc = DGControl.PendingXfers.EndXfer(ref _appIdentity, ref _currentDS, ref pending);
|
||||||
// DoTransferAudio();
|
break;
|
||||||
//}
|
}
|
||||||
//else // just defaults to image
|
|
||||||
//{
|
|
||||||
// DoTransferImage();
|
|
||||||
//}
|
|
||||||
|
|
||||||
} while (rc == TWRC.SUCCESS && pending.Count != 0);
|
} while (rc == TWRC.SUCCESS && pending.Count != 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user