mirror of
https://github.com/soukoku/ntwain.git
synced 2026-02-25 13:04:07 +08:00
Updated readme and added some more ctors.
This commit is contained in:
30
LICENSE.txt
30
LICENSE.txt
@@ -1,8 +1,32 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2012 - 2021 Eugene Wang
|
Copyright (c) 2012 - 2023 Eugene Wang
|
||||||
|
|
||||||
Copyright(C) 2013 - 2020 Kodak Alaris Inc.
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# for twaincs
|
||||||
|
|
||||||
|
|
||||||
|
Copyright(C) 2013 - 2021 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
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -1,19 +1,18 @@
|
|||||||
# TWAIN dotnet library
|
# TWAIN dotnet library
|
||||||
|
|
||||||
NOTE: This is a rewrite test that's based off twaincs from
|
NOTE: This is a rewrite test that internally uses
|
||||||
the TWAIN Working Group and doesn't fully work yet.
|
[twaincs](https://github.com/twain/twain-cs) from
|
||||||
Use V3 branch for current version.
|
the TWAIN Working Group. It doesn't fully work yet.
|
||||||
|
Use V3 branch for the current version.
|
||||||
|
|
||||||
## Info
|
## Info
|
||||||
|
|
||||||
This is a dotnet library created to make working with
|
This is a dotnet library created to make working with
|
||||||
[TWAIN](http://twain.org/) easier.
|
[TWAIN](http://twain.org/) devices easier in dotnet.
|
||||||
V4 of this lib has these goals:
|
V4 of this lib has these goals:
|
||||||
|
|
||||||
* Targets latest TWAIN version (2.4 as of this writing).
|
* Targets latest TWAIN version (2.5).
|
||||||
* Supports all the TWAIN functions in the spec (directly or through dotnet wrapper).
|
* Supports full framework and netcore apps (if the framework is still supported).
|
||||||
* Works with both 32 or 64 bit data sources as appropriate for the 32 or 64 bit apps.
|
|
||||||
* Supports full framework (4.5+) and netcore apps.
|
|
||||||
|
|
||||||
## Using the lib
|
## Using the lib
|
||||||
|
|
||||||
|
|||||||
459
src/NTwain/Extensions/TWAINH_EXTRAS.cs
Normal file
459
src/NTwain/Extensions/TWAINH_EXTRAS.cs
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using static TWAINWorkingGroup.TWAIN;
|
||||||
|
|
||||||
|
namespace TWAINWorkingGroup
|
||||||
|
{
|
||||||
|
// this contains my additions under the TWAINWorkingGroup namespace
|
||||||
|
// that makes some twain types easier to work with.
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TWAIN's boolean values.
|
||||||
|
/// </summary>
|
||||||
|
public enum BoolType : ushort
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The false value (0).
|
||||||
|
/// </summary>
|
||||||
|
False = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// The true value (1).
|
||||||
|
/// </summary>
|
||||||
|
True = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A more dotnet-friendly representation of <see cref="TW_METRICS"/>.
|
||||||
|
/// </summary>
|
||||||
|
public struct Metrics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Return code of querying the metrics.
|
||||||
|
/// </summary>
|
||||||
|
public STS ReturnCode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of sheets of paper processed by the scanner.
|
||||||
|
/// </summary>
|
||||||
|
public int Sheets;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of images made available for transfer by the driver. This is not
|
||||||
|
/// necessarily the same as the number of images actually transferred, since the
|
||||||
|
/// application may opt to skip transfers or to end without transferring all images.
|
||||||
|
/// </summary>
|
||||||
|
public int Images;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TwainDirectTaskResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Return code of task.
|
||||||
|
/// </summary>
|
||||||
|
public STS ReturnCode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The response of the task in JSON if successful.
|
||||||
|
/// </summary>
|
||||||
|
public string ResponseJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TValue"></typeparam>
|
||||||
|
public class Enumeration<TValue> where TValue : struct
|
||||||
|
{
|
||||||
|
public int CurrentIndex;
|
||||||
|
|
||||||
|
public int DefaultIndex;
|
||||||
|
|
||||||
|
public TValue[] Items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A more dotnet-friendly representation of <see cref="TW_RANGE"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TValue"></typeparam>
|
||||||
|
public partial class Range<TValue> : IEnumerable<TValue> where TValue : struct
|
||||||
|
{
|
||||||
|
public TValue MinValue;
|
||||||
|
public TValue MaxValue;
|
||||||
|
public TValue StepSize;
|
||||||
|
public TValue DefaultValue;
|
||||||
|
public TValue CurrentValue;
|
||||||
|
|
||||||
|
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
|
||||||
|
{
|
||||||
|
if (!(MinValue is IConvertible))
|
||||||
|
throw new NotSupportedException($"The value type {typeof(TValue).Name} is not supported for range enumeration.");
|
||||||
|
|
||||||
|
return new DynamicEnumerator(MinValue, MaxValue, StepSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return ((IEnumerable<TValue>)this).GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynamic is a cheap hack to sidestep the compiler restrictions if I know TValue is numeric
|
||||||
|
class DynamicEnumerator : IEnumerator<TValue>
|
||||||
|
{
|
||||||
|
private readonly TValue _min;
|
||||||
|
private readonly TValue _max;
|
||||||
|
private readonly TValue _step;
|
||||||
|
private TValue _cur;
|
||||||
|
bool started = false;
|
||||||
|
|
||||||
|
public DynamicEnumerator(TValue min, TValue max, TValue step)
|
||||||
|
{
|
||||||
|
_min = min;
|
||||||
|
_max = max;
|
||||||
|
_step = step;
|
||||||
|
_cur = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue Current => _cur;
|
||||||
|
|
||||||
|
object IEnumerator.Current => this.Current;
|
||||||
|
|
||||||
|
public void Dispose() { }
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
if (!started)
|
||||||
|
{
|
||||||
|
started = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = _cur + (dynamic)_step;
|
||||||
|
if (next == _cur || next < _min || next > _max) return false;
|
||||||
|
|
||||||
|
_cur = next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_cur = _min;
|
||||||
|
started = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
partial class TWAIN
|
||||||
|
{
|
||||||
|
partial struct TW_FIX32 : IEquatable<TW_FIX32>, IConvertible
|
||||||
|
{
|
||||||
|
// the conversion logic is found in the spec.
|
||||||
|
|
||||||
|
float ToFloat()
|
||||||
|
{
|
||||||
|
return Whole + Frac / 65536f;
|
||||||
|
}
|
||||||
|
double ToDouble()
|
||||||
|
{
|
||||||
|
return Whole + Frac / 65536.0;
|
||||||
|
}
|
||||||
|
public TW_FIX32(double value)
|
||||||
|
{
|
||||||
|
Whole = (short)value;
|
||||||
|
Frac = (ushort)((value - Whole) * 65536.0);
|
||||||
|
}
|
||||||
|
public TW_FIX32(float value)
|
||||||
|
{
|
||||||
|
//int temp = (int)(value * 65536.0 + 0.5);
|
||||||
|
//Whole = (short)(temp >> 16);
|
||||||
|
//Fraction = (ushort)(temp & 0x0000ffff);
|
||||||
|
|
||||||
|
// different version from twain faq
|
||||||
|
bool sign = value < 0;
|
||||||
|
int temp = (int)(value * 65536.0 + (sign ? (-0.5) : 0.5));
|
||||||
|
Whole = (short)(temp >> 16);
|
||||||
|
Frac = (ushort)(temp & 0x0000ffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return ToFloat().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(TW_FIX32 other)
|
||||||
|
{
|
||||||
|
return Whole == other.Whole && Frac == other.Frac;
|
||||||
|
}
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is TW_FIX32 other)
|
||||||
|
{
|
||||||
|
return Equals(other);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Whole ^ Frac;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region IConvertable
|
||||||
|
|
||||||
|
TypeCode IConvertible.GetTypeCode()
|
||||||
|
{
|
||||||
|
return TypeCode.Single;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IConvertible.ToBoolean(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return this != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte IConvertible.ToByte(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToByte((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
char IConvertible.ToChar(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToChar((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime IConvertible.ToDateTime(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToDateTime((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
decimal IConvertible.ToDecimal(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToDecimal((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
double IConvertible.ToDouble(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToDouble((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
short IConvertible.ToInt16(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToInt16((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int IConvertible.ToInt32(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToInt32((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
long IConvertible.ToInt64(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToInt64((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
sbyte IConvertible.ToSByte(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToSByte((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
float IConvertible.ToSingle(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToSingle((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
string IConvertible.ToString(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return this.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ChangeType((float)this, conversionType, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
ushort IConvertible.ToUInt16(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToUInt16((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint IConvertible.ToUInt32(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToUInt32((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong IConvertible.ToUInt64(IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return Convert.ToUInt64((float)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public static implicit operator float(TW_FIX32 value) => value.ToFloat();
|
||||||
|
public static implicit operator TW_FIX32(float value) => new TW_FIX32(value);
|
||||||
|
|
||||||
|
public static implicit operator double(TW_FIX32 value) => value.ToDouble();
|
||||||
|
public static implicit operator TW_FIX32(double value) => new TW_FIX32((float)value);
|
||||||
|
|
||||||
|
public static bool operator ==(TW_FIX32 value1, TW_FIX32 value2) => value1.Equals(value2);
|
||||||
|
public static bool operator !=(TW_FIX32 value1, TW_FIX32 value2) => !value1.Equals(value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial struct TW_FRAME : IEquatable<TW_FRAME>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates <see cref="TW_FRAME"/> from a string representation of it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public TW_FRAME(string value) : this()
|
||||||
|
{
|
||||||
|
var parts = value.Split(',');
|
||||||
|
if (parts.Length == 4)
|
||||||
|
{
|
||||||
|
Left = float.Parse(parts[0]);
|
||||||
|
Top = float.Parse(parts[1]);
|
||||||
|
Right = float.Parse(parts[2]);
|
||||||
|
Bottom = float.Parse(parts[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Cannot create frame from \"{value}\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// String representation of Left,Top,Right,Bottom.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Left},{Top},{Right},{Bottom}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(TW_FRAME other)
|
||||||
|
{
|
||||||
|
return Left == other.Left && Top == other.Top &&
|
||||||
|
Right == other.Right && Bottom == other.Bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is TW_FRAME other)
|
||||||
|
{
|
||||||
|
return Equals(other);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Left.GetHashCode() ^ Top.GetHashCode() ^
|
||||||
|
Right.GetHashCode() ^ Bottom.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool operator ==(TW_FRAME value1, TW_FRAME value2)
|
||||||
|
{
|
||||||
|
return value1.Equals(value2);
|
||||||
|
}
|
||||||
|
public static bool operator !=(TW_FRAME value1, TW_FRAME value2)
|
||||||
|
{
|
||||||
|
return !value1.Equals(value2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
partial struct TW_STR32
|
||||||
|
{
|
||||||
|
public const int Size = 34;
|
||||||
|
|
||||||
|
public TW_STR32(string value) : this()
|
||||||
|
{
|
||||||
|
Set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(TW_STR32 value) => value.ToString();
|
||||||
|
public static explicit operator TW_STR32(string value) => new TW_STR32(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
partial struct TW_STR64
|
||||||
|
{
|
||||||
|
public const int Size = 66;
|
||||||
|
|
||||||
|
public TW_STR64(string value) : this()
|
||||||
|
{
|
||||||
|
Set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(TW_STR64 value) => value.ToString();
|
||||||
|
public static explicit operator TW_STR64(string value) => new TW_STR64(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial struct TW_STR128
|
||||||
|
{
|
||||||
|
public const int Size = 130;
|
||||||
|
|
||||||
|
public TW_STR128(string value) : this()
|
||||||
|
{
|
||||||
|
Set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(TW_STR128 value) => value.ToString();
|
||||||
|
public static explicit operator TW_STR128(string value) => new TW_STR128(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial struct TW_STR255
|
||||||
|
{
|
||||||
|
public const int Size = 256;
|
||||||
|
|
||||||
|
public TW_STR255(string value) : this()
|
||||||
|
{
|
||||||
|
Set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(TW_STR255 value) => value.ToString();
|
||||||
|
public static explicit operator TW_STR255(string value) => new TW_STR255(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial struct TW_IDENTITY
|
||||||
|
{
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Manufacturer} - {ProductName} {Version} (TWAIN {ProtocolMajor}.{ProtocolMinor})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
partial struct TW_VERSION
|
||||||
|
{
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{MajorNum}.{MinorNum}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//partial struct TW_DEVICEEVENT
|
||||||
|
//{
|
||||||
|
// public TWDE Event { get { return (TWDE)_event; } }
|
||||||
|
// public TWFL FlashUsed2 { get { return (TWFL)_flashUsed2; } }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>NTwain</PackageId>
|
<PackageId>NTwain</PackageId>
|
||||||
<Description>Library containing the TWAIN API for dotnet.</Description>
|
<Description>Library containing the TWAIN API for dotnet.</Description>
|
||||||
<TargetFrameworks>net462;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
|
<TargetFrameworks>net462;netcoreapp3.1;net5.0;net6.0;net7.0;netstandard2.0</TargetFrameworks>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>10.0</LangVersion>
|
<LangVersion>11</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,462 +0,0 @@
|
|||||||
using NTwain;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using static TWAINWorkingGroup.TWAIN;
|
|
||||||
|
|
||||||
namespace TWAINWorkingGroup
|
|
||||||
{
|
|
||||||
// contains my additions that makes twain types easier to work with.
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// TWAIN's boolean values.
|
|
||||||
/// </summary>
|
|
||||||
public enum BoolType : ushort
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The false value (0).
|
|
||||||
/// </summary>
|
|
||||||
False = 0,
|
|
||||||
/// <summary>
|
|
||||||
/// The true value (1).
|
|
||||||
/// </summary>
|
|
||||||
True = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A more dotnet-friendly representation of <see cref="TW_METRICS"/>.
|
|
||||||
/// </summary>
|
|
||||||
public struct Metrics
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Return code of querying the metrics.
|
|
||||||
/// </summary>
|
|
||||||
public STS ReturnCode;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The number of sheets of paper processed by the scanner.
|
|
||||||
/// </summary>
|
|
||||||
public int Sheets;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The number of images made available for transfer by the driver. This is not
|
|
||||||
/// necessarily the same as the number of images actually transferred, since the
|
|
||||||
/// application may opt to skip transfers or to end without transferring all images.
|
|
||||||
/// </summary>
|
|
||||||
public int Images;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct TwainDirectTaskResult
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Return code of task.
|
|
||||||
/// </summary>
|
|
||||||
public STS ReturnCode;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The response of the task in JSON if successful.
|
|
||||||
/// </summary>
|
|
||||||
public string ResponseJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TValue"></typeparam>
|
|
||||||
public class Enumeration<TValue> where TValue : struct
|
|
||||||
{
|
|
||||||
public int CurrentIndex;
|
|
||||||
|
|
||||||
public int DefaultIndex;
|
|
||||||
|
|
||||||
public TValue[] Items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A more dotnet-friendly representation of <see cref="TW_RANGE"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TValue"></typeparam>
|
|
||||||
public partial class Range<TValue> : IEnumerable<TValue> where TValue : struct
|
|
||||||
{
|
|
||||||
public TValue MinValue;
|
|
||||||
public TValue MaxValue;
|
|
||||||
public TValue StepSize;
|
|
||||||
public TValue DefaultValue;
|
|
||||||
public TValue CurrentValue;
|
|
||||||
|
|
||||||
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
|
|
||||||
{
|
|
||||||
if (!(MinValue is IConvertible))
|
|
||||||
throw new NotSupportedException($"The value type {typeof(TValue).Name} is not supported for range enumeration.");
|
|
||||||
|
|
||||||
return new DynamicEnumerator(MinValue, MaxValue, StepSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return ((IEnumerable<TValue>)this).GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
// dynamic is a cheap hack to sidestep the compiler restrictions if I know TValue is numeric
|
|
||||||
class DynamicEnumerator : IEnumerator<TValue>
|
|
||||||
{
|
|
||||||
private readonly TValue _min;
|
|
||||||
private readonly TValue _max;
|
|
||||||
private readonly TValue _step;
|
|
||||||
private TValue _cur;
|
|
||||||
bool started = false;
|
|
||||||
|
|
||||||
public DynamicEnumerator(TValue min, TValue max, TValue step)
|
|
||||||
{
|
|
||||||
_min = min;
|
|
||||||
_max = max;
|
|
||||||
_step = step;
|
|
||||||
_cur = min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue Current => _cur;
|
|
||||||
|
|
||||||
object IEnumerator.Current => this.Current;
|
|
||||||
|
|
||||||
public void Dispose() { }
|
|
||||||
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
if (!started)
|
|
||||||
{
|
|
||||||
started = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var next = _cur + (dynamic)_step;
|
|
||||||
if (next == _cur || next < _min || next > _max) return false;
|
|
||||||
|
|
||||||
_cur = next;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
_cur = _min;
|
|
||||||
started = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
partial class TWAIN
|
|
||||||
{
|
|
||||||
partial struct TW_FIX32 : IEquatable<TW_FIX32>, IConvertible
|
|
||||||
{
|
|
||||||
// the conversion logic is found in the spec.
|
|
||||||
|
|
||||||
float ToFloat()
|
|
||||||
{
|
|
||||||
return Whole + Frac / 65536f;
|
|
||||||
}
|
|
||||||
double ToDouble()
|
|
||||||
{
|
|
||||||
return Whole + Frac / 65536.0;
|
|
||||||
}
|
|
||||||
public TW_FIX32(double value)
|
|
||||||
{
|
|
||||||
Whole = (short)value;
|
|
||||||
Frac = (ushort)((value - Whole) * 65536.0);
|
|
||||||
}
|
|
||||||
public TW_FIX32(float value)
|
|
||||||
{
|
|
||||||
//int temp = (int)(value * 65536.0 + 0.5);
|
|
||||||
//Whole = (short)(temp >> 16);
|
|
||||||
//Fraction = (ushort)(temp & 0x0000ffff);
|
|
||||||
|
|
||||||
// different version from twain faq
|
|
||||||
bool sign = value < 0;
|
|
||||||
int temp = (int)(value * 65536.0 + (sign ? (-0.5) : 0.5));
|
|
||||||
Whole = (short)(temp >> 16);
|
|
||||||
Frac = (ushort)(temp & 0x0000ffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return ToFloat().ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(TW_FIX32 other)
|
|
||||||
{
|
|
||||||
return Whole == other.Whole && Frac == other.Frac;
|
|
||||||
}
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
if (obj is TW_FIX32 other)
|
|
||||||
{
|
|
||||||
return Equals(other);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return Whole ^ Frac;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#region IConvertable
|
|
||||||
|
|
||||||
TypeCode IConvertible.GetTypeCode()
|
|
||||||
{
|
|
||||||
return TypeCode.Single;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IConvertible.ToBoolean(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return this != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte IConvertible.ToByte(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToByte((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
char IConvertible.ToChar(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToChar((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
DateTime IConvertible.ToDateTime(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToDateTime((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
decimal IConvertible.ToDecimal(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToDecimal((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
double IConvertible.ToDouble(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToDouble((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
short IConvertible.ToInt16(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToInt16((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
int IConvertible.ToInt32(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToInt32((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
long IConvertible.ToInt64(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToInt64((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
sbyte IConvertible.ToSByte(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToSByte((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
float IConvertible.ToSingle(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToSingle((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
string IConvertible.ToString(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return this.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ChangeType((float)this, conversionType, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
ushort IConvertible.ToUInt16(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToUInt16((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint IConvertible.ToUInt32(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToUInt32((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong IConvertible.ToUInt64(IFormatProvider provider)
|
|
||||||
{
|
|
||||||
return Convert.ToUInt64((float)this);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public static implicit operator float(TW_FIX32 value) => value.ToFloat();
|
|
||||||
public static implicit operator TW_FIX32(float value) => new TW_FIX32(value);
|
|
||||||
|
|
||||||
public static implicit operator double(TW_FIX32 value) => value.ToDouble();
|
|
||||||
public static implicit operator TW_FIX32(double value) => new TW_FIX32((float)value);
|
|
||||||
|
|
||||||
public static bool operator ==(TW_FIX32 value1, TW_FIX32 value2) => value1.Equals(value2);
|
|
||||||
public static bool operator !=(TW_FIX32 value1, TW_FIX32 value2) => !value1.Equals(value2);
|
|
||||||
}
|
|
||||||
|
|
||||||
partial struct TW_FRAME : IEquatable<TW_FRAME>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Creates <see cref="TW_FRAME"/> from a string representation of it.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value"></param>
|
|
||||||
public TW_FRAME(string value) : this()
|
|
||||||
{
|
|
||||||
var parts = value.Split(',');
|
|
||||||
if (parts.Length == 4)
|
|
||||||
{
|
|
||||||
Left = float.Parse(parts[0]);
|
|
||||||
Top = float.Parse(parts[1]);
|
|
||||||
Right = float.Parse(parts[2]);
|
|
||||||
Bottom = float.Parse(parts[3]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"Cannot create frame from \"{value}\".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// String representation of Left,Top,Right,Bottom.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{Left},{Top},{Right},{Bottom}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(TW_FRAME other)
|
|
||||||
{
|
|
||||||
return Left == other.Left && Top == other.Top &&
|
|
||||||
Right == other.Right && Bottom == other.Bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
if (obj is TW_FRAME other)
|
|
||||||
{
|
|
||||||
return Equals(other);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return Left.GetHashCode() ^ Top.GetHashCode() ^
|
|
||||||
Right.GetHashCode() ^ Bottom.GetHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static bool operator ==(TW_FRAME value1, TW_FRAME value2)
|
|
||||||
{
|
|
||||||
return value1.Equals(value2);
|
|
||||||
}
|
|
||||||
public static bool operator !=(TW_FRAME value1, TW_FRAME value2)
|
|
||||||
{
|
|
||||||
return !value1.Equals(value2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
partial struct TW_STR32
|
|
||||||
{
|
|
||||||
public const int Size = 34;
|
|
||||||
|
|
||||||
public TW_STR32(string value) : this()
|
|
||||||
{
|
|
||||||
Set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(TW_STR32 value) => value.ToString();
|
|
||||||
public static explicit operator TW_STR32(string value) => new TW_STR32(value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
partial struct TW_STR64
|
|
||||||
{
|
|
||||||
public const int Size = 66;
|
|
||||||
|
|
||||||
public TW_STR64(string value) : this()
|
|
||||||
{
|
|
||||||
Set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(TW_STR64 value) => value.ToString();
|
|
||||||
public static explicit operator TW_STR64(string value) => new TW_STR64(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
partial struct TW_STR128
|
|
||||||
{
|
|
||||||
public const int Size = 130;
|
|
||||||
|
|
||||||
public TW_STR128(string value) : this()
|
|
||||||
{
|
|
||||||
Set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(TW_STR128 value) => value.ToString();
|
|
||||||
public static explicit operator TW_STR128(string value) => new TW_STR128(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
partial struct TW_STR255
|
|
||||||
{
|
|
||||||
public const int Size = 256;
|
|
||||||
|
|
||||||
public TW_STR255(string value) : this()
|
|
||||||
{
|
|
||||||
Set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator string(TW_STR255 value) => value.ToString();
|
|
||||||
public static explicit operator TW_STR255(string value) => new TW_STR255(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
partial struct TW_IDENTITY
|
|
||||||
{
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{Manufacturer} - {ProductName} {Version} (TWAIN {ProtocolMajor}.{ProtocolMinor})";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
partial struct TW_VERSION
|
|
||||||
{
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{MajorNum}.{MinorNum}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//partial struct TW_DEVICEEVENT
|
|
||||||
//{
|
|
||||||
// public TWDE Event { get { return (TWDE)_event; } }
|
|
||||||
// public TWFL FlashUsed2 { get { return (TWFL)_flashUsed2; } }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using TWAINWorkingGroup;
|
using TWAINWorkingGroup;
|
||||||
using static TWAINWorkingGroup.TWAIN;
|
using static TWAINWorkingGroup.TWAIN;
|
||||||
|
|
||||||
namespace NTwain
|
namespace NTwain
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A wrapper around the low-level <see cref="TWAIN"/> object
|
||||||
|
/// that may be easier to use in dotnet with typical scenarios.
|
||||||
|
/// </summary>
|
||||||
public class TwainSession : IDisposable
|
public class TwainSession : IDisposable
|
||||||
{
|
{
|
||||||
private TWAIN _twain;
|
private TWAIN _twain;
|
||||||
@@ -21,14 +21,24 @@ namespace NTwain
|
|||||||
private readonly IThreadMarshaller _threadMarshaller;
|
private readonly IThreadMarshaller _threadMarshaller;
|
||||||
private IntPtr _hWnd;
|
private IntPtr _hWnd;
|
||||||
|
|
||||||
public TwainSession(Assembly application,
|
public TwainSession(Assembly applicationInfo,
|
||||||
|
IThreadMarshaller threadMarshaller, IntPtr hWnd,
|
||||||
|
TWLG language = TWLG.ENGLISH_USA, TWCY country = TWCY.USA) :
|
||||||
|
this(FileVersionInfo.GetVersionInfo(applicationInfo.Location),
|
||||||
|
threadMarshaller, hWnd, language, country)
|
||||||
|
{ }
|
||||||
|
public TwainSession(FileVersionInfo applicationInfo,
|
||||||
|
IThreadMarshaller threadMarshaller, IntPtr hWnd,
|
||||||
|
TWLG language = TWLG.ENGLISH_USA, TWCY country = TWCY.USA) :
|
||||||
|
this(applicationInfo.CompanyName, applicationInfo.ProductName, applicationInfo.ProductName,
|
||||||
|
threadMarshaller, hWnd, language, country)
|
||||||
|
{ }
|
||||||
|
public TwainSession(string companyName, string productFamily, string productName,
|
||||||
IThreadMarshaller threadMarshaller, IntPtr hWnd,
|
IThreadMarshaller threadMarshaller, IntPtr hWnd,
|
||||||
TWLG language = TWLG.ENGLISH_USA, TWCY country = TWCY.USA)
|
TWLG language = TWLG.ENGLISH_USA, TWCY country = TWCY.USA)
|
||||||
{
|
{
|
||||||
var info = FileVersionInfo.GetVersionInfo(application.Location);
|
|
||||||
|
|
||||||
_twain = new TWAIN(
|
_twain = new TWAIN(
|
||||||
info.CompanyName, info.ProductName, info.ProductName,
|
companyName, productFamily, 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,
|
country, "", language, 2, 4, false, true,
|
||||||
@@ -67,7 +77,7 @@ namespace NTwain
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the low-level twain object.
|
/// Gets the low-level twain object.
|
||||||
/// Only use if you know what you're doing.
|
/// Only use it if you know what you're doing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TWAIN TWAIN { get { return _twain; } }
|
public TWAIN TWAIN { get { return _twain; } }
|
||||||
|
|
||||||
@@ -149,7 +159,7 @@ namespace NTwain
|
|||||||
|
|
||||||
if (_twain.IsMsgCloseDsReq() || _twain.IsMsgCloseDsOk())
|
if (_twain.IsMsgCloseDsReq() || _twain.IsMsgCloseDsOk())
|
||||||
{
|
{
|
||||||
StepDown(STATE.S4);
|
_twain.Rollback(STATE.S4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +220,7 @@ namespace NTwain
|
|||||||
// TODO: may be wrong for now
|
// TODO: may be wrong for now
|
||||||
if (pending.Count == 0 || sts == STS.CANCEL || sts == STS.XFERDONE)
|
if (pending.Count == 0 || sts == STS.CANCEL || sts == STS.XFERDONE)
|
||||||
{
|
{
|
||||||
StepDown(STATE.S4);
|
_twain.Rollback(STATE.S4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -316,7 +326,7 @@ namespace NTwain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
StepDown(STATE.S2);
|
_twain.Rollback(STATE.S2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -380,7 +390,7 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
StepDown(STATE.S3);
|
_twain.Rollback(STATE.S3);
|
||||||
if (value.HasValue)
|
if (value.HasValue)
|
||||||
{
|
{
|
||||||
var twidentity = value.Value;
|
var twidentity = value.Value;
|
||||||
@@ -389,53 +399,6 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Steps down the TWAIN state to the specified state.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="target"></param>
|
|
||||||
public void StepDown(STATE target)
|
|
||||||
{
|
|
||||||
// Make sure we have something to work with...
|
|
||||||
if (_twain == null) return;
|
|
||||||
|
|
||||||
// Walk the states, we don't care about the status returns. Basically,
|
|
||||||
// these need to work, or we're guaranteed to hang...
|
|
||||||
|
|
||||||
// 7 --> 6
|
|
||||||
if ((State == STATE.S7) && (target < STATE.S7))
|
|
||||||
{
|
|
||||||
TW_PENDINGXFERS twpendingxfers = default;
|
|
||||||
_twain.DatPendingxfers(DG.CONTROL, MSG.ENDXFER, ref twpendingxfers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6 --> 5
|
|
||||||
if ((State == STATE.S6) && (target < STATE.S6))
|
|
||||||
{
|
|
||||||
TW_PENDINGXFERS twpendingxfers = default;
|
|
||||||
_twain.DatPendingxfers(DG.CONTROL, MSG.RESET, ref twpendingxfers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5 --> 4
|
|
||||||
if ((State == STATE.S5) && (target < STATE.S5))
|
|
||||||
{
|
|
||||||
TW_USERINTERFACE twuserinterface = default;
|
|
||||||
_twain.DatUserinterface(DG.CONTROL, MSG.DISABLEDS, ref twuserinterface);
|
|
||||||
SourceDisabled?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4 --> 3
|
|
||||||
if ((State == STATE.S4) && (target < STATE.S4))
|
|
||||||
{
|
|
||||||
_caps = null;
|
|
||||||
_twain.DatIdentity(DG.CONTROL, MSG.CLOSEDS, ref _twain.m_twidentityDs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3 --> 2
|
|
||||||
if ((State == STATE.S3) && (target < STATE.S3))
|
|
||||||
{
|
|
||||||
_twain.DatParent(DG.CONTROL, MSG.CLOSEDSM, ref _hWnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Capabilities _caps;
|
private Capabilities _caps;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user