mirror of
https://github.com/soukoku/ntwain.git
synced 2026-01-26 13:39:47 +08:00
Added source selection methods.
This commit is contained in:
@@ -15,6 +15,7 @@ namespace NetCoreConsole
|
||||
.Build();
|
||||
Console.WriteLine($"App = {(config.Is64Bit ? "64bit" : "32bit")}");
|
||||
Console.WriteLine($"Platform = {config.Platform}");
|
||||
Console.WriteLine();
|
||||
|
||||
using (var session = new TwainSession(config))
|
||||
{
|
||||
@@ -23,18 +24,33 @@ namespace NetCoreConsole
|
||||
var handle = IntPtr.Zero;
|
||||
if (session.Open(ref handle) == NTwain.Data.ReturnCode.Success)
|
||||
{
|
||||
Console.WriteLine("Available data sources:");
|
||||
foreach (var src in session.GetSources())
|
||||
{
|
||||
Console.WriteLine($"\t{src}");
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
var defaultSrc = session.DefaultSource;
|
||||
Console.WriteLine($"Default data source = {defaultSrc}");
|
||||
Console.WriteLine();
|
||||
|
||||
var selectSrc = session.ShowSourceSelector();
|
||||
Console.WriteLine($"Selected data source = {selectSrc}");
|
||||
Console.WriteLine();
|
||||
|
||||
//session.DefaultSource = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Console.WriteLine("Test ended, press Enter to exit...");
|
||||
Console.ReadLine();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("ERROR: " + ex.ToString());
|
||||
}
|
||||
|
||||
Console.WriteLine("Test ended, press Enter to exit...");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
private static void Session_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
|
||||
@@ -310,7 +310,7 @@ namespace NTwain.Data
|
||||
partial class TW_IDENTITY
|
||||
{
|
||||
// TODO: id needs to be 64bit in 64bit?
|
||||
TW_UINT32 _id;
|
||||
internal TW_UINT32 Id;
|
||||
TW_VERSION _version;
|
||||
TW_UINT16 _protocolMajor;
|
||||
TW_UINT16 _protocolMinor;
|
||||
|
||||
@@ -1584,7 +1584,8 @@ namespace NTwain.Data
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}.{1} {2}", Major, Minor, Info);
|
||||
if (Info == null) return $"v{Major}.{Minor}";
|
||||
return $"v{Major}.{Minor} ({Info})";
|
||||
}
|
||||
|
||||
#region equals
|
||||
|
||||
45
src/NTwain/DataSource.cs
Normal file
45
src/NTwain/DataSource.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NTwain.Data;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
/// <summary>
|
||||
/// A TWAIN data source.
|
||||
/// </summary>
|
||||
public class DataSource
|
||||
{
|
||||
internal readonly TwainSession Session;
|
||||
|
||||
internal TW_IDENTITY Identity { get; }
|
||||
|
||||
internal DataSource(TwainSession session, TW_IDENTITY src)
|
||||
{
|
||||
this.Session = session;
|
||||
this.Identity = src;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source name.
|
||||
/// </summary>
|
||||
public string Name => Identity.ProductName;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source version info.
|
||||
/// </summary>
|
||||
public TW_VERSION Version => Identity.Version;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name} {Version}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,25 @@
|
||||
namespace NTwain.Triplets
|
||||
using System;
|
||||
|
||||
namespace NTwain.Triplets
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for grouping triplet operations.
|
||||
/// </summary>
|
||||
public abstract class BaseTriplet
|
||||
{
|
||||
protected TwainSession session;
|
||||
/// <summary>
|
||||
/// Gets the associated <see cref="TwainSession"/>.
|
||||
/// </summary>
|
||||
protected readonly TwainSession Session;
|
||||
|
||||
public BaseTriplet(TwainSession session)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseTriplet" /> class.
|
||||
/// </summary>
|
||||
/// <param name="session">The session.</param>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
protected BaseTriplet(TwainSession session)
|
||||
{
|
||||
this.session = session;
|
||||
this.Session = session ?? throw new ArgumentNullException(nameof(session));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace NTwain.Triplets
|
||||
public ReturnCode Get(out TW_ENTRYPOINT entryPoint)
|
||||
{
|
||||
entryPoint = new TW_ENTRYPOINT();
|
||||
return NativeMethods.DsmWin32(session.Config.AppWin32, null,
|
||||
return NativeMethods.DsmWin32(Session.Config.AppWin32, null,
|
||||
DataGroups.Control, DataArgumentType.EntryPoint, Message.Get, entryPoint);
|
||||
}
|
||||
}
|
||||
|
||||
70
src/NTwain/Triplets/DGControl.Identity.cs
Normal file
70
src/NTwain/Triplets/DGControl.Identity.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using NTwain.Data;
|
||||
using NTwain.Internals;
|
||||
using System;
|
||||
|
||||
namespace NTwain.Triplets
|
||||
{
|
||||
sealed class Identity : BaseTriplet
|
||||
{
|
||||
internal Identity(TwainSession session) : base(session) { }
|
||||
|
||||
public ReturnCode CloseDS(TW_IDENTITY source)
|
||||
{
|
||||
var rc = NativeMethods.DsmWin32(Session.Config.AppWin32, IntPtr.Zero,
|
||||
DataGroups.Control, DataArgumentType.Identity, Message.CloseDS, source);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
Session.State = TwainState.S3;
|
||||
Session.CurrentSource = null;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public ReturnCode GetDefault(out TW_IDENTITY source)
|
||||
{
|
||||
source = new TW_IDENTITY();
|
||||
return NativeMethods.DsmWin32(Session.Config.AppWin32, IntPtr.Zero,
|
||||
DataGroups.Control, DataArgumentType.Identity, Message.GetDefault, source);
|
||||
}
|
||||
|
||||
|
||||
public ReturnCode GetFirst(out TW_IDENTITY source)
|
||||
{
|
||||
source = new TW_IDENTITY();
|
||||
return NativeMethods.DsmWin32(Session.Config.AppWin32, IntPtr.Zero,
|
||||
DataGroups.Control, DataArgumentType.Identity, Message.GetFirst, source);
|
||||
}
|
||||
|
||||
public ReturnCode GetNext(out TW_IDENTITY source)
|
||||
{
|
||||
source = new TW_IDENTITY();
|
||||
return NativeMethods.DsmWin32(Session.Config.AppWin32, IntPtr.Zero,
|
||||
DataGroups.Control, DataArgumentType.Identity, Message.GetNext, source);
|
||||
}
|
||||
|
||||
public ReturnCode OpenDS(TW_IDENTITY source)
|
||||
{
|
||||
var rc = NativeMethods.DsmWin32(Session.Config.AppWin32, IntPtr.Zero,
|
||||
DataGroups.Control, DataArgumentType.Identity, Message.OpenDS, source);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
Session.CurrentSource = Session.GetSourceSingleton(source);
|
||||
Session.State = TwainState.S4;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public ReturnCode Set(DataSource source)
|
||||
{
|
||||
return NativeMethods.DsmWin32(Session.Config.AppWin32, IntPtr.Zero,
|
||||
DataGroups.Control, DataArgumentType.Identity, Message.Set, source?.Identity);
|
||||
}
|
||||
|
||||
public ReturnCode UserSelect(out TW_IDENTITY source)
|
||||
{
|
||||
source = new TW_IDENTITY();
|
||||
return NativeMethods.DsmWin32(Session.Config.AppWin32, IntPtr.Zero,
|
||||
DataGroups.Control, DataArgumentType.Identity, Message.UserSelect, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,20 +12,20 @@ namespace NTwain.Triplets
|
||||
|
||||
public ReturnCode OpenDSM(ref IntPtr hWnd)
|
||||
{
|
||||
var rc = NativeMethods.DsmWin32(session.Config.AppWin32, null,
|
||||
var rc = NativeMethods.DsmWin32(Session.Config.AppWin32, null,
|
||||
DataGroups.Control, DataArgumentType.Parent, Message.OpenDSM, ref hWnd);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
session.State = TwainState.DsmOpened;
|
||||
Session.State = TwainState.DsmOpened;
|
||||
|
||||
// if twain2 then get memory management functions
|
||||
if ((session.Config.AppWin32.DataFunctionalities & DataFunctionalities.Dsm2) == DataFunctionalities.Dsm2)
|
||||
if ((Session.Config.AppWin32.DataFunctionalities & DataFunctionalities.Dsm2) == DataFunctionalities.Dsm2)
|
||||
{
|
||||
TW_ENTRYPOINT entry;
|
||||
rc = session.DGControl.EntryPoint.Get(out entry);
|
||||
rc = Session.DGControl.EntryPoint.Get(out entry);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
session.Config.MemoryManager = entry;
|
||||
Session.Config.MemoryManager = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -38,9 +38,9 @@ namespace NTwain.Triplets
|
||||
|
||||
public ReturnCode CloseDSM(ref IntPtr hWnd)
|
||||
{
|
||||
var rc = NativeMethods.DsmWin32(session.Config.AppWin32, null, DataGroups.Control,
|
||||
var rc = NativeMethods.DsmWin32(Session.Config.AppWin32, null, DataGroups.Control,
|
||||
DataArgumentType.Parent, Message.CloseDSM, ref hWnd);
|
||||
if (rc == ReturnCode.Success) session.State = TwainState.DsmLoaded;
|
||||
if (rc == ReturnCode.Success) Session.State = TwainState.DsmLoaded;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,12 @@ namespace NTwain.Triplets
|
||||
internal DGControl(TwainSession session) : base(session) { }
|
||||
|
||||
Parent _parent;
|
||||
internal Parent Parent => _parent ?? (_parent = new Parent(session));
|
||||
internal Parent Parent => _parent ?? (_parent = new Parent(Session));
|
||||
|
||||
EntryPoint _entryPoint;
|
||||
internal EntryPoint EntryPoint => _entryPoint ?? (_entryPoint = new EntryPoint(session));
|
||||
internal EntryPoint EntryPoint => _entryPoint ?? (_entryPoint = new EntryPoint(Session));
|
||||
|
||||
Identity _identity;
|
||||
internal Identity Identity => _identity ?? (_identity = new Identity(Session));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace NTwain
|
||||
/// </summary>
|
||||
public class TwainConfigBuilder
|
||||
{
|
||||
private bool _legacy;
|
||||
//private bool _legacy;
|
||||
private string _appName;
|
||||
private Version _version;
|
||||
private string _companyName;
|
||||
|
||||
@@ -8,22 +8,41 @@ using System.Text;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages a TWAIN session.
|
||||
/// </summary>
|
||||
public partial class TwainSession
|
||||
{
|
||||
internal TwainConfig Config;
|
||||
internal readonly TwainConfig Config;
|
||||
private IntPtr _hWnd;
|
||||
// cache generated twain sources so if you get same source from same session it'll return the same object
|
||||
readonly Dictionary<string, DataSource> _ownedSources = new Dictionary<string, DataSource>();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="TwainSession"/>.
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public TwainSession(TwainConfig config)
|
||||
{
|
||||
Config = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the TWAIN session.
|
||||
/// </summary>
|
||||
/// <param name="hWnd"></param>
|
||||
/// <returns></returns>
|
||||
public ReturnCode Open(ref IntPtr hWnd)
|
||||
{
|
||||
_hWnd = hWnd;
|
||||
return DGControl.Parent.OpenDSM(ref hWnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Steps down to the target session state.
|
||||
/// </summary>
|
||||
/// <param name="targetState"></param>
|
||||
/// <returns></returns>
|
||||
public ReturnCode StepDown(TwainState targetState)
|
||||
{
|
||||
var rc = ReturnCode.Failure;
|
||||
@@ -39,5 +58,82 @@ namespace NTwain
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets list of sources available on the machine.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<DataSource> GetSources()
|
||||
{
|
||||
TW_IDENTITY srcId;
|
||||
var rc = DGControl.Identity.GetFirst(out srcId);
|
||||
while (rc == ReturnCode.Success)
|
||||
{
|
||||
yield return GetSourceSingleton(srcId);
|
||||
rc = DGControl.Identity.GetNext(out srcId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the default data source.
|
||||
/// </summary>
|
||||
public DataSource DefaultSource
|
||||
{
|
||||
get
|
||||
{
|
||||
TW_IDENTITY src;
|
||||
if (DGControl.Identity.GetDefault(out src) == ReturnCode.Success)
|
||||
{
|
||||
return GetSourceSingleton(src);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
//if (value != null && value.Session != this)
|
||||
//{
|
||||
// throw new InvalidOperationException("Source is not from this session.");
|
||||
//}
|
||||
DGControl.Identity.Set(value);
|
||||
RaisePropertyChanged(nameof(DefaultSource));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to show the built-in source selector dialog and return the selected source.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DataSource ShowSourceSelector()
|
||||
{
|
||||
TW_IDENTITY id;
|
||||
if (DGControl.Identity.UserSelect(out id) == ReturnCode.Success)
|
||||
{
|
||||
return GetSourceSingleton(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently open data source.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current source.
|
||||
/// </value>
|
||||
public DataSource CurrentSource { get; internal set; }
|
||||
|
||||
internal DataSource GetSourceSingleton(TW_IDENTITY sourceId)
|
||||
{
|
||||
DataSource source = null;
|
||||
var key = $"{sourceId.Id}|{sourceId.Manufacturer}|{sourceId.ProductFamily}|{sourceId.ProductName}";
|
||||
if (_ownedSources.ContainsKey(key))
|
||||
{
|
||||
source = _ownedSources[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
_ownedSources[key] = source = new DataSource(this, sourceId);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user