Test idea of wrapping source identity into .net class.

This commit is contained in:
soukoku
2014-05-19 20:48:21 -04:00
parent f17692184f
commit e879c00102
50 changed files with 511 additions and 693 deletions

View File

@@ -8,6 +8,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
@@ -18,6 +19,16 @@ namespace NTwain
/// </summary>
public class TwainSession : ITwainSessionInternal
{
/// <summary>
/// Initializes a new instance of the <see cref="TwainSession"/> class.
/// </summary>
/// <param name="supportedGroups">The supported groups.</param>
public TwainSession(DataGroups supportedGroups)
: this(TWIdentity.CreateFromAssembly(supportedGroups, Assembly.GetEntryAssembly()))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TwainSession" /> class.
/// </summary>
@@ -81,9 +92,9 @@ namespace NTwain
return new TentativeStateCommitable(this, newState);
}
void ITwainSessionInternal.ChangeSourceId(TWIdentity sourceId)
void ITwainSessionInternal.ChangeSourceId(TwainSource source)
{
SourceId = sourceId;
Source = source;
OnPropertyChanged("SourceId");
SafeAsyncSyncableRaiseOnEvent(OnSourceChanged, SourceChanged);
}
@@ -106,12 +117,12 @@ namespace NTwain
#region ITwainSession Members
/// <summary>
/// Gets the source id used for the session.
/// Gets the currently open source.
/// </summary>
/// <value>
/// The source id.
/// The current source.
/// </value>
public TWIdentity SourceId { get; private set; }
public TwainSource Source { get; private set; }
int _state;
/// <summary>
@@ -135,30 +146,41 @@ namespace NTwain
}
static readonly CapabilityId[] _emptyCapList = new CapabilityId[0];
private IList<CapabilityId> _supportedCaps;
/// <summary>
/// Gets the supported caps for the currently open source.
/// Gets list of sources available in the system.
/// Only call this at state 2 or higher.
/// </summary>
/// <value>
/// The supported caps.
/// </value>
public IList<CapabilityId> SupportedCaps
/// <param name="session">The session.</param>
/// <returns></returns>
public IList<TwainSource> GetSources()
{
get
List<TwainSource> list = new List<TwainSource>();
// now enumerate
TWIdentity srcId;
var rc = DGControl.Identity.GetFirst(out srcId);
if (rc == ReturnCode.Success) { list.Add(new TwainSource(this, srcId)); }
do
{
if (_supportedCaps == null && State > 3)
rc = DGControl.Identity.GetNext(out srcId);
if (rc == ReturnCode.Success)
{
_supportedCaps = this.GetCapabilities();
list.Add(new TwainSource(this, srcId));
}
return _supportedCaps ?? _emptyCapList;
}
private set
{
_supportedCaps = value;
OnPropertyChanged("SupportedCaps");
}
} while (rc == ReturnCode.Success);
return list;
}
/// <summary>
/// Gets the manager status. Only call this at state 2 or higher.
/// </summary>
/// <param name="session">The session.</param>
/// <returns></returns>
public TWStatus GetStatus()
{
TWStatus stat;
DGControl.Status.GetManager(out stat);
return stat;
}
#endregion
@@ -315,55 +337,6 @@ namespace NTwain
return rc;
}
/// <summary>
/// Loads the specified source into main memory and causes its initialization.
/// Calls to this must be followed by
/// <see cref="CloseSource" /> when not using it anymore.
/// </summary>
/// <param name="sourceProductName">Name of the source.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentException">sourceProductName</exception>
public ReturnCode OpenSource(string sourceProductName)
{
if (string.IsNullOrEmpty(sourceProductName)) { throw new ArgumentException(Resources.SourceRequired, "sourceProductName"); }
var rc = ReturnCode.Failure;
MessageLoop.Instance.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId));
var source = new TWIdentity
{
ProductName = sourceProductName
};
rc = DGControl.Identity.OpenDS(source);
});
return rc;
}
/// <summary>
/// When an application is finished with a Source, it must formally close the session between them
/// using this operation. This is necessary in case the Source only supports connection with a single
/// application (many desktop scanners will behave this way). A Source such as this cannot be
/// accessed by other applications until its current session is terminated
/// </summary>
/// <returns></returns>
public ReturnCode CloseSource()
{
var rc = ReturnCode.Failure;
MessageLoop.Instance.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId));
rc = DGControl.Identity.CloseDS();
if (rc == ReturnCode.Success)
{
SupportedCaps = null;
}
});
return rc;
}
/// <summary>
/// Enables the source to start transferring.
@@ -372,7 +345,7 @@ namespace NTwain
/// <param name="modal">if set to <c>true</c> any driver UI will display as modal.</param>
/// <param name="windowHandle">The window handle if modal.</param>
/// <returns></returns>
public ReturnCode EnableSource(SourceEnableMode mode, bool modal, IntPtr windowHandle)
ReturnCode ITwainSessionInternal.EnableSource(SourceEnableMode mode, bool modal, IntPtr windowHandle)
{
var rc = ReturnCode.Failure;
@@ -488,7 +461,7 @@ namespace NTwain
}
if (targetState < 4)
{
CloseSource();
Source.Close();
}
if (targetState < 3)
{
@@ -507,7 +480,7 @@ namespace NTwain
/// </summary>
public event EventHandler StateChanged;
/// <summary>
/// Occurs when <see cref="SourceId"/> has changed.
/// Occurs when <see cref="Source"/> has changed.
/// </summary>
public event EventHandler SourceChanged;
/// <summary>
@@ -608,7 +581,7 @@ namespace NTwain
protected virtual void OnStateChanged() { }
/// <summary>
/// Called when <see cref="SourceId"/> changed.
/// Called when <see cref="Source"/> changed.
/// </summary>
protected virtual void OnSourceChanged() { }
@@ -676,7 +649,7 @@ namespace NTwain
ReturnCode HandleCallback(TWIdentity origin, TWIdentity destination, DataGroups dg, DataArgumentType dat, Message msg, IntPtr data)
{
if (origin != null && SourceId != null && origin.Id == SourceId.Id && _state >= 5)
if (origin != null && Source != null && origin.Id == Source.Identity.Id && _state >= 5)
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CallbackHandler at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, msg));
// spec says we must handle this on the thread that enabled the DS.