diff --git a/NTwain/ITwainSession.cs b/NTwain/ITwainSession.cs
new file mode 100644
index 0000000..862e715
--- /dev/null
+++ b/NTwain/ITwainSession.cs
@@ -0,0 +1,63 @@
+using NTwain.Data;
+using System;
+using System.ComponentModel;
+namespace NTwain
+{
+ ///
+ /// Interface for keeping track of current TWAIN state with current app and source ids.
+ ///
+ public interface ITwainSession : INotifyPropertyChanged
+ {
+ ///
+ /// Gets the app id used for the session.
+ ///
+ /// The app id.
+ TWIdentity AppId { get; }
+
+ ///
+ /// Gets the source id used for the session.
+ ///
+ /// The source id.
+ TWIdentity SourceId { get; }
+
+ ///
+ /// Gets the current state number as defined by the TWAIN spec.
+ ///
+ /// The state.
+ int State { get; }
+ }
+
+ ///
+ /// Internal interface for state management.
+ ///
+ interface ITwainSessionInternal : ITwainSession
+ {
+ ///
+ /// Gets or sets a value indicating whether calls to triplets will verify the current twain session state.
+ ///
+ ///
+ /// true if state value is enforced; otherwise, false.
+ ///
+ bool EnforceState { get; set; }
+
+ ///
+ /// Changes the state right away.
+ ///
+ /// The new state.
+ /// if set to true to notify change.
+ void ChangeState(int newState, bool notifyChange);
+
+ ///
+ /// Gets the pending state changer and tentatively changes the session state to the specified value.
+ /// Value will only stick if committed.
+ ///
+ /// The new state.
+ ///
+ ICommitable GetPendingStateChanger(int newState);
+ }
+
+ interface ICommitable : IDisposable
+ {
+ void Commit();
+ }
+}
diff --git a/NTwain/NTwain.csproj b/NTwain/NTwain.csproj
index f095da2..93cb51d 100644
--- a/NTwain/NTwain.csproj
+++ b/NTwain/NTwain.csproj
@@ -60,6 +60,7 @@
+
True
diff --git a/NTwain/Properties/VersionInfo.cs b/NTwain/Properties/VersionInfo.cs
index d474805..d6fe60d 100644
--- a/NTwain/Properties/VersionInfo.cs
+++ b/NTwain/Properties/VersionInfo.cs
@@ -14,6 +14,6 @@ namespace NTwain
// keep this same in majors releases
public const string Release = "0.8.0.0";
// change this for each nuget release
- public const string Build = "0.8.0";
+ public const string Build = "0.8.1";
}
}
\ No newline at end of file
diff --git a/NTwain/Triplets/DGAudio/DGAudio.AudioFileXfer.cs b/NTwain/Triplets/DGAudio/DGAudio.AudioFileXfer.cs
index dbd7366..f344ee2 100644
--- a/NTwain/Triplets/DGAudio/DGAudio.AudioFileXfer.cs
+++ b/NTwain/Triplets/DGAudio/DGAudio.AudioFileXfer.cs
@@ -5,7 +5,7 @@ namespace NTwain.Triplets
{
sealed class AudioFileXfer : OpBase
{
- internal AudioFileXfer(TwainSession session) : base(session) { }
+ internal AudioFileXfer(ITwainSessionInternal session) : base(session) { }
///
/// This operation is used to initiate the transfer of audio from the Source to the application via the
/// disk-file transfer mechanism. It causes the transfer to begin.
diff --git a/NTwain/Triplets/DGAudio/DGAudio.AudioInfo.cs b/NTwain/Triplets/DGAudio/DGAudio.AudioInfo.cs
index 102c1b0..b9e22db 100644
--- a/NTwain/Triplets/DGAudio/DGAudio.AudioInfo.cs
+++ b/NTwain/Triplets/DGAudio/DGAudio.AudioInfo.cs
@@ -5,7 +5,7 @@ namespace NTwain.Triplets
{
public sealed class AudioInfo : OpBase
{
- internal AudioInfo(TwainSession session) : base(session) { }
+ internal AudioInfo(ITwainSessionInternal session) : base(session) { }
///
/// Used to get the information of the current audio data ready to transfer.
///
diff --git a/NTwain/Triplets/DGAudio/DGAudio.AudioNativeXfer.cs b/NTwain/Triplets/DGAudio/DGAudio.AudioNativeXfer.cs
index bd41a3d..cdd13c0 100644
--- a/NTwain/Triplets/DGAudio/DGAudio.AudioNativeXfer.cs
+++ b/NTwain/Triplets/DGAudio/DGAudio.AudioNativeXfer.cs
@@ -5,7 +5,7 @@ namespace NTwain.Triplets
{
sealed class AudioNativeXfer : OpBase
{
- internal AudioNativeXfer(TwainSession session) : base(session) { }
+ internal AudioNativeXfer(ITwainSessionInternal session) : base(session) { }
///
/// Causes the transfer of an audio data from the Source to the application, via the Native
/// transfer mechanism, to begin. The resulting data is stored in main memory in a single block.
diff --git a/NTwain/Triplets/DGAudio/DGAudio.cs b/NTwain/Triplets/DGAudio/DGAudio.cs
index 19e3158..789c0e7 100644
--- a/NTwain/Triplets/DGAudio/DGAudio.cs
+++ b/NTwain/Triplets/DGAudio/DGAudio.cs
@@ -6,8 +6,8 @@ namespace NTwain.Triplets
///
public sealed class DGAudio
{
- TwainSession _session;
- internal DGAudio(TwainSession session)
+ ITwainSessionInternal _session;
+ internal DGAudio(ITwainSessionInternal session)
{
if (session == null) { throw new ArgumentNullException("session"); }
_session = session;
diff --git a/NTwain/Triplets/DGControl/DGControl.Callback.cs b/NTwain/Triplets/DGControl/DGControl.Callback.cs
index 2d31162..8867ffd 100644
--- a/NTwain/Triplets/DGControl/DGControl.Callback.cs
+++ b/NTwain/Triplets/DGControl/DGControl.Callback.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class Callback : OpBase
{
- internal Callback(TwainSession session) : base(session) { }
+ internal Callback(ITwainSessionInternal session) : base(session) { }
///
/// This triplet is sent to the DSM by the Application to register the application’s entry point with
/// the DSM, so that the DSM can use callbacks to inform the application of events generated by the
diff --git a/NTwain/Triplets/DGControl/DGControl.Callback2.cs b/NTwain/Triplets/DGControl/DGControl.Callback2.cs
index 2749d7c..f0d47d0 100644
--- a/NTwain/Triplets/DGControl/DGControl.Callback2.cs
+++ b/NTwain/Triplets/DGControl/DGControl.Callback2.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class Callback2 : OpBase
{
- internal Callback2(TwainSession session) : base(session) { }
+ internal Callback2(ITwainSessionInternal session) : base(session) { }
///
/// This triplet is sent to the DSM by the Application to register the application’s entry point with
/// the DSM, so that the DSM can use callbacks to inform the application of events generated by the
diff --git a/NTwain/Triplets/DGControl/DGControl.Capability.cs b/NTwain/Triplets/DGControl/DGControl.Capability.cs
index 3109109..15b0f9a 100644
--- a/NTwain/Triplets/DGControl/DGControl.Capability.cs
+++ b/NTwain/Triplets/DGControl/DGControl.Capability.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class Capability : OpBase
{
- internal Capability(TwainSession session) : base(session) { }
+ internal Capability(ITwainSessionInternal session) : base(session) { }
///
/// Returns the Source’s Current, Default and Available Values for a specified capability.
///
diff --git a/NTwain/Triplets/DGControl/DGControl.CustomDSData.cs b/NTwain/Triplets/DGControl/DGControl.CustomDSData.cs
index b152733..40fa3a4 100644
--- a/NTwain/Triplets/DGControl/DGControl.CustomDSData.cs
+++ b/NTwain/Triplets/DGControl/DGControl.CustomDSData.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class CustomDSData : OpBase
{
- internal CustomDSData(TwainSession session) : base(session) { }
+ internal CustomDSData(ITwainSessionInternal session) : base(session) { }
///
/// This operation is used by the application to query the data source for its current settings, e.g.
/// DPI, paper size, color format. The actual format of the data is data source dependent and not
diff --git a/NTwain/Triplets/DGControl/DGControl.DeviceEvent.cs b/NTwain/Triplets/DGControl/DGControl.DeviceEvent.cs
index 56222b6..b33fb39 100644
--- a/NTwain/Triplets/DGControl/DGControl.DeviceEvent.cs
+++ b/NTwain/Triplets/DGControl/DGControl.DeviceEvent.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class DeviceEvent : OpBase
{
- internal DeviceEvent(TwainSession session) : base(session) { }
+ internal DeviceEvent(ITwainSessionInternal session) : base(session) { }
public ReturnCode Get(out TWDeviceEvent sourceDeviceEvent)
{
Session.VerifyState(4, 7, DataGroups.Control, DataArgumentType.DeviceEvent, Message.Get);
diff --git a/NTwain/Triplets/DGControl/DGControl.EntryPoint.cs b/NTwain/Triplets/DGControl/DGControl.EntryPoint.cs
index 0e500d9..0674753 100644
--- a/NTwain/Triplets/DGControl/DGControl.EntryPoint.cs
+++ b/NTwain/Triplets/DGControl/DGControl.EntryPoint.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class EntryPoint : OpBase
{
- internal EntryPoint(TwainSession session) : base(session) { }
+ internal EntryPoint(ITwainSessionInternal session) : base(session) { }
///
/// Gets the function entry points for twain 2.0 or higher.
///
diff --git a/NTwain/Triplets/DGControl/DGControl.Event.cs b/NTwain/Triplets/DGControl/DGControl.Event.cs
index ff95d42..9342882 100644
--- a/NTwain/Triplets/DGControl/DGControl.Event.cs
+++ b/NTwain/Triplets/DGControl/DGControl.Event.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class Event : OpBase
{
- internal Event(TwainSession session) : base(session) { }
+ internal Event(ITwainSessionInternal session) : base(session) { }
///
/// This operation supports the distribution of events from the application to Sources so that the
diff --git a/NTwain/Triplets/DGControl/DGControl.FileSystem.cs b/NTwain/Triplets/DGControl/DGControl.FileSystem.cs
index 91c8bc2..eb0b292 100644
--- a/NTwain/Triplets/DGControl/DGControl.FileSystem.cs
+++ b/NTwain/Triplets/DGControl/DGControl.FileSystem.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class FileSystem : OpBase
{
- internal FileSystem(TwainSession session) : base(session) { }
+ internal FileSystem(ITwainSessionInternal session) : base(session) { }
///
/// This operation selects the destination directory within the Source (camera, storage, etc), where
/// images captured using CapAutomaticCapture will be stored. This command only selects
diff --git a/NTwain/Triplets/DGControl/DGControl.Identity.cs b/NTwain/Triplets/DGControl/DGControl.Identity.cs
index ee14587..5441ed6 100644
--- a/NTwain/Triplets/DGControl/DGControl.Identity.cs
+++ b/NTwain/Triplets/DGControl/DGControl.Identity.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class Identity : OpBase
{
- internal Identity(TwainSession session) : base(session) { }
+ internal Identity(ITwainSessionInternal session) : base(session) { }
///
/// 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
@@ -19,8 +19,8 @@ namespace NTwain.Triplets
Session.VerifyState(4, 4, DataGroups.Control, DataArgumentType.Identity, Message.CloseDS);
var rc = PInvoke.DsmEntry(Session.AppId, Message.CloseDS, Session.SourceId);
if (rc == ReturnCode.Success)
- {
- Session.State = 3;
+ {
+ Session.ChangeState(3, true);
}
return rc;
}
@@ -74,8 +74,8 @@ namespace NTwain.Triplets
Session.VerifyState(3, 3, DataGroups.Control, DataArgumentType.Identity, Message.OpenDS);
var rc = PInvoke.DsmEntry(Session.AppId, Message.OpenDS, source);
if (rc == ReturnCode.Success)
- {
- Session.State = 4;
+ {
+ Session.ChangeState(4, true);
}
return rc;
}
diff --git a/NTwain/Triplets/DGControl/DGControl.Parent.cs b/NTwain/Triplets/DGControl/DGControl.Parent.cs
index 7ea598f..3157ef8 100644
--- a/NTwain/Triplets/DGControl/DGControl.Parent.cs
+++ b/NTwain/Triplets/DGControl/DGControl.Parent.cs
@@ -7,7 +7,7 @@ namespace NTwain.Triplets
{
sealed class Parent : OpBase
{
- internal Parent(TwainSession session) : base(session) { }
+ internal Parent(ITwainSessionInternal session) : base(session) { }
///
/// When the application has closed all the Sources it had previously opened, and is finished with
@@ -23,7 +23,7 @@ namespace NTwain.Triplets
var rc = PInvoke.DsmEntry(Session.AppId, null, DataGroups.Control, DataArgumentType.Parent, Message.CloseDsm, ref handle);
if (rc == ReturnCode.Success)
{
- Session.State = 2;
+ Session.ChangeState(2, true);
}
return rc;
}
@@ -41,7 +41,7 @@ namespace NTwain.Triplets
var rc = PInvoke.DsmEntry(Session.AppId, null, DataGroups.Control, DataArgumentType.Parent, Message.OpenDsm, ref handle);
if (rc == ReturnCode.Success)
{
- Session.State = 3;
+ Session.ChangeState(3, true);
}
return rc;
}
diff --git a/NTwain/Triplets/DGControl/DGControl.PassThru.cs b/NTwain/Triplets/DGControl/DGControl.PassThru.cs
index 416519d..414d466 100644
--- a/NTwain/Triplets/DGControl/DGControl.PassThru.cs
+++ b/NTwain/Triplets/DGControl/DGControl.PassThru.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class PassThru : OpBase
{
- internal PassThru(TwainSession session) : base(session) { }
+ internal PassThru(ITwainSessionInternal session) : base(session) { }
///
/// PASSTHRU is intended for the use of Source writers writing diagnostic applications. It allows
/// raw communication with the currently selected device in the Source.
diff --git a/NTwain/Triplets/DGControl/DGControl.PendingXfers.cs b/NTwain/Triplets/DGControl/DGControl.PendingXfers.cs
index e275aa8..94f537e 100644
--- a/NTwain/Triplets/DGControl/DGControl.PendingXfers.cs
+++ b/NTwain/Triplets/DGControl/DGControl.PendingXfers.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class PendingXfers : OpBase
{
- internal PendingXfers(TwainSession session) : base(session) { }
+ internal PendingXfers(ITwainSessionInternal session) : base(session) { }
///
/// This triplet is used to cancel or terminate a transfer. Issued in state 6, this triplet cancels the next
/// pending transfer, discards the transfer data, and decrements the pending transfers count. In
diff --git a/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs b/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs
index 1a90a95..690d56a 100644
--- a/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs
+++ b/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class SetupFileXfer : OpBase
{
- internal SetupFileXfer(TwainSession session) : base(session) { }
+ internal SetupFileXfer(ITwainSessionInternal session) : base(session) { }
///
/// Returns information about the file into which the Source has or will put the acquired image
/// or audio data.
diff --git a/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs b/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs
index 42fca56..c10be6a 100644
--- a/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs
+++ b/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class SetupMemXfer : OpBase
{
- internal SetupMemXfer(TwainSession session) : base(session) { }
+ internal SetupMemXfer(ITwainSessionInternal session) : base(session) { }
///
/// Returns the Source’s preferred, minimum, and maximum allocation sizes for transfer memory
/// buffers.
diff --git a/NTwain/Triplets/DGControl/DGControl.Status.cs b/NTwain/Triplets/DGControl/DGControl.Status.cs
index c54b869..d6873e5 100644
--- a/NTwain/Triplets/DGControl/DGControl.Status.cs
+++ b/NTwain/Triplets/DGControl/DGControl.Status.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class Status : OpBase
{
- internal Status(TwainSession session) : base(session) { }
+ internal Status(ITwainSessionInternal session) : base(session) { }
///
/// Returns the current Condition Code for the Source Manager.
///
diff --git a/NTwain/Triplets/DGControl/DGControl.StatusUtf8.cs b/NTwain/Triplets/DGControl/DGControl.StatusUtf8.cs
index 9badf4f..b857109 100644
--- a/NTwain/Triplets/DGControl/DGControl.StatusUtf8.cs
+++ b/NTwain/Triplets/DGControl/DGControl.StatusUtf8.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class StatusUtf8 : OpBase
{
- internal StatusUtf8(TwainSession session) : base(session) { }
+ internal StatusUtf8(ITwainSessionInternal session) : base(session) { }
///
/// Translate the contents of a TW_STATUS structure received from a Source into a localized UTF-8
/// encoded string.
diff --git a/NTwain/Triplets/DGControl/DGControl.UserInterface.cs b/NTwain/Triplets/DGControl/DGControl.UserInterface.cs
index 1c2faa1..10e4d25 100644
--- a/NTwain/Triplets/DGControl/DGControl.UserInterface.cs
+++ b/NTwain/Triplets/DGControl/DGControl.UserInterface.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class UserInterface : OpBase
{
- internal UserInterface(TwainSession session) : base(session) { }
+ internal UserInterface(ITwainSessionInternal session) : base(session) { }
///
/// This operation causes the Source’s user interface, if displayed during the
/// EnableDS operation, to be lowered. The Source is returned to
@@ -23,7 +23,7 @@ namespace NTwain.Triplets
var rc = PInvoke.DsmEntry(Session.AppId, Session.SourceId, Message.DisableDS, userInterface);
if (rc == ReturnCode.Success)
{
- Session.State = 4;
+ Session.ChangeState(4, true);
}
return rc;
}
diff --git a/NTwain/Triplets/DGControl/DGControl.XferGroup.cs b/NTwain/Triplets/DGControl/DGControl.XferGroup.cs
index 7a93820..f9c37b3 100644
--- a/NTwain/Triplets/DGControl/DGControl.XferGroup.cs
+++ b/NTwain/Triplets/DGControl/DGControl.XferGroup.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class XferGroup : OpBase
{
- internal XferGroup(TwainSession session) : base(session) { }
+ internal XferGroup(ITwainSessionInternal session) : base(session) { }
///
/// Returns the Data Group (the type of data) for the upcoming transfer. The Source is required to
/// only supply one of the DGs specified in the SupportedGroups field of origin.
diff --git a/NTwain/Triplets/DGControl/DGControl.cs b/NTwain/Triplets/DGControl/DGControl.cs
index cbc7bf2..f475586 100644
--- a/NTwain/Triplets/DGControl/DGControl.cs
+++ b/NTwain/Triplets/DGControl/DGControl.cs
@@ -6,8 +6,8 @@ namespace NTwain.Triplets
///
public sealed class DGControl
{
- TwainSession _session;
- internal DGControl(TwainSession session)
+ ITwainSessionInternal _session;
+ internal DGControl(ITwainSessionInternal session)
{
if (session == null) { throw new ArgumentNullException("session"); }
_session = session;
diff --git a/NTwain/Triplets/DGImage/DGImage.CieColor.cs b/NTwain/Triplets/DGImage/DGImage.CieColor.cs
index 9aa8576..ada1bf5 100644
--- a/NTwain/Triplets/DGImage/DGImage.CieColor.cs
+++ b/NTwain/Triplets/DGImage/DGImage.CieColor.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class CieColor : OpBase
{
- internal CieColor(TwainSession session) : base(session) { }
+ internal CieColor(ITwainSessionInternal session) : base(session) { }
///
/// This operation causes the Source to report the currently active parameters to be used in
diff --git a/NTwain/Triplets/DGImage/DGImage.ExtImageInfo.cs b/NTwain/Triplets/DGImage/DGImage.ExtImageInfo.cs
index ef3a81a..ab8007d 100644
--- a/NTwain/Triplets/DGImage/DGImage.ExtImageInfo.cs
+++ b/NTwain/Triplets/DGImage/DGImage.ExtImageInfo.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class ExtImageInfo : OpBase
{
- internal ExtImageInfo(TwainSession session) : base(session) { }
+ internal ExtImageInfo(ITwainSessionInternal session) : base(session) { }
public ReturnCode Get(TWExtImageInfo info)
{
diff --git a/NTwain/Triplets/DGImage/DGImage.GrayResponse.cs b/NTwain/Triplets/DGImage/DGImage.GrayResponse.cs
index f3be249..3315506 100644
--- a/NTwain/Triplets/DGImage/DGImage.GrayResponse.cs
+++ b/NTwain/Triplets/DGImage/DGImage.GrayResponse.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class GrayResponse : OpBase
{
- internal GrayResponse(TwainSession session) : base(session) { }
+ internal GrayResponse(ITwainSessionInternal session) : base(session) { }
///
/// The Reset operation causes the Source to use its "identity response curve." The identity
diff --git a/NTwain/Triplets/DGImage/DGImage.IccProfile.cs b/NTwain/Triplets/DGImage/DGImage.IccProfile.cs
index e37796d..50024ba 100644
--- a/NTwain/Triplets/DGImage/DGImage.IccProfile.cs
+++ b/NTwain/Triplets/DGImage/DGImage.IccProfile.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class IccProfile : OpBase
{
- internal IccProfile(TwainSession session) : base(session) { }
+ internal IccProfile(ITwainSessionInternal session) : base(session) { }
///
/// This operation provides the application with the ICC profile associated with the image which is
diff --git a/NTwain/Triplets/DGImage/DGImage.ImageFileXfer.cs b/NTwain/Triplets/DGImage/DGImage.ImageFileXfer.cs
index b954962..640b051 100644
--- a/NTwain/Triplets/DGImage/DGImage.ImageFileXfer.cs
+++ b/NTwain/Triplets/DGImage/DGImage.ImageFileXfer.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class ImageFileXfer : OpBase
{
- internal ImageFileXfer(TwainSession session) : base(session) { }
+ internal ImageFileXfer(ITwainSessionInternal session) : base(session) { }
///
/// This operation is used to initiate the transfer of an image from the Source to the application via
diff --git a/NTwain/Triplets/DGImage/DGImage.ImageInfo.cs b/NTwain/Triplets/DGImage/DGImage.ImageInfo.cs
index 83ceecb..80747aa 100644
--- a/NTwain/Triplets/DGImage/DGImage.ImageInfo.cs
+++ b/NTwain/Triplets/DGImage/DGImage.ImageInfo.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class ImageInfo : OpBase
{
- internal ImageInfo(TwainSession session) : base(session) { }
+ internal ImageInfo(ITwainSessionInternal session) : base(session) { }
public ReturnCode Get(out TWImageInfo info)
{
diff --git a/NTwain/Triplets/DGImage/DGImage.ImageLayout.cs b/NTwain/Triplets/DGImage/DGImage.ImageLayout.cs
index 332948a..5933cee 100644
--- a/NTwain/Triplets/DGImage/DGImage.ImageLayout.cs
+++ b/NTwain/Triplets/DGImage/DGImage.ImageLayout.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class ImageLayout : OpBase
{
- internal ImageLayout(TwainSession session) : base(session) { }
+ internal ImageLayout(ITwainSessionInternal session) : base(session) { }
public ReturnCode Get(out TWImageLayout layout)
{
diff --git a/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs b/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs
index 251e16e..2788959 100644
--- a/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs
+++ b/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class ImageMemFileXfer : OpBase
{
- internal ImageMemFileXfer(TwainSession session) : base(session) { }
+ internal ImageMemFileXfer(ITwainSessionInternal session) : base(session) { }
///
/// This operation is used to initiate the transfer of an image from the Source to the application via
diff --git a/NTwain/Triplets/DGImage/DGImage.ImageMemXfer.cs b/NTwain/Triplets/DGImage/DGImage.ImageMemXfer.cs
index 5379d2a..b060e24 100644
--- a/NTwain/Triplets/DGImage/DGImage.ImageMemXfer.cs
+++ b/NTwain/Triplets/DGImage/DGImage.ImageMemXfer.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class ImageMemXfer : OpBase
{
- internal ImageMemXfer(TwainSession session) : base(session) { }
+ internal ImageMemXfer(ITwainSessionInternal session) : base(session) { }
///
/// This operation is used to initiate the transfer of an image from the Source to the application via
diff --git a/NTwain/Triplets/DGImage/DGImage.ImageNativeXfer.cs b/NTwain/Triplets/DGImage/DGImage.ImageNativeXfer.cs
index be80486..c827d9b 100644
--- a/NTwain/Triplets/DGImage/DGImage.ImageNativeXfer.cs
+++ b/NTwain/Triplets/DGImage/DGImage.ImageNativeXfer.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
sealed class ImageNativeXfer : OpBase
{
- internal ImageNativeXfer(TwainSession session) : base(session) { }
+ internal ImageNativeXfer(ITwainSessionInternal session) : base(session) { }
///
/// Causes the transfer of an image’s data from the Source to the application, via the Native transfer
diff --git a/NTwain/Triplets/DGImage/DGImage.JpegCompression.cs b/NTwain/Triplets/DGImage/DGImage.JpegCompression.cs
index 1ce6489..8c06f7f 100644
--- a/NTwain/Triplets/DGImage/DGImage.JpegCompression.cs
+++ b/NTwain/Triplets/DGImage/DGImage.JpegCompression.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class JpegCompression : OpBase
{
- internal JpegCompression(TwainSession session) : base(session) { }
+ internal JpegCompression(ITwainSessionInternal session) : base(session) { }
///
/// Causes the Source to return the parameters that will be used during the compression of data
diff --git a/NTwain/Triplets/DGImage/DGImage.Palette8.cs b/NTwain/Triplets/DGImage/DGImage.Palette8.cs
index 2e2514c..47557d0 100644
--- a/NTwain/Triplets/DGImage/DGImage.Palette8.cs
+++ b/NTwain/Triplets/DGImage/DGImage.Palette8.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class Palette8 : OpBase
{
- internal Palette8(TwainSession session) : base(session) { }
+ internal Palette8(ITwainSessionInternal session) : base(session) { }
///
/// This operation causes the Source to report its current palette information.
diff --git a/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs b/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs
index 1f2fba7..cc74923 100644
--- a/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs
+++ b/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
{
public sealed class RgbResponse : OpBase
{
- internal RgbResponse(TwainSession session) : base(session) { }
+ internal RgbResponse(ITwainSessionInternal session) : base(session) { }
///
/// Causes the Source to use its "identity" response curves for future RGB transfers. The identity
diff --git a/NTwain/Triplets/DGImage/DGImage.cs b/NTwain/Triplets/DGImage/DGImage.cs
index d42ce9c..1543877 100644
--- a/NTwain/Triplets/DGImage/DGImage.cs
+++ b/NTwain/Triplets/DGImage/DGImage.cs
@@ -6,8 +6,8 @@ namespace NTwain.Triplets
///
public sealed class DGImage
{
- TwainSession _session;
- internal DGImage(TwainSession session)
+ ITwainSessionInternal _session;
+ internal DGImage(ITwainSessionInternal session)
{
if (session == null) { throw new ArgumentNullException("session"); }
_session = session;
diff --git a/NTwain/Triplets/OpBase.cs b/NTwain/Triplets/OpBase.cs
index ad72de6..4fcbc13 100644
--- a/NTwain/Triplets/OpBase.cs
+++ b/NTwain/Triplets/OpBase.cs
@@ -11,16 +11,15 @@ namespace NTwain.Triplets
///
public abstract class OpBase
{
- TwainSession _session;
///
/// Initializes a new instance of the class.
///
/// The session.
///
- protected OpBase(TwainSession session)
+ internal OpBase(ITwainSessionInternal session)
{
if (session == null) { throw new ArgumentNullException("session"); }
- _session = session;
+ Session = session;
}
///
@@ -29,6 +28,6 @@ namespace NTwain.Triplets
///
/// The session.
///
- protected TwainSession Session { get { return _session; } }
+ internal ITwainSessionInternal Session { get; private set; }
}
}
diff --git a/NTwain/TwainSession.cs b/NTwain/TwainSession.cs
index 13d85d5..8c35c8c 100644
--- a/NTwain/TwainSession.cs
+++ b/NTwain/TwainSession.cs
@@ -19,7 +19,7 @@ namespace NTwain
///
/// Provides a session for working with TWAIN api in an application.
///
- public class TwainSession : IMessageFilter, INotifyPropertyChanged
+ public class TwainSession : ITwainSessionInternal, IMessageFilter, INotifyPropertyChanged
{
///
/// Initializes a new instance of the class.
@@ -62,21 +62,11 @@ namespace NTwain
}
}
- int _state;
///
/// Gets the current state number as defined by the TWAIN spec.
///
/// The state.
- public int State
- {
- get { return _state; }
- internal set
- {
- Debug.WriteLine("TWAIN State = " + value);
- _state = value;
- RaisePropertyChanged("State");
- }
- }
+ public int State { get; private set; }
///
/// Gets or sets a value indicating whether callback is used parts of source communication
@@ -165,32 +155,20 @@ namespace NTwain
#endregion
- #region quickies
+ #region state transition calls
-
- ///
- /// Verifies the session is within the specified state range (inclusive). Throws
- /// if violated.
- ///
- /// The allowed minimum.
- /// The allowed maximum.
- /// The triplet data group.
- /// The triplet data argument type.
- /// The triplet message.
- ///
- internal void VerifyState(int allowedMinimum, int allowedMaximum, DataGroups group, DataArgumentType dataArgumentType, NTwain.Values.Message message)
+ void ITwainSessionInternal.ChangeState(int newState, bool notifyChange)
{
- if (EnforceState && (State < allowedMinimum || State > allowedMaximum))
- {
- throw new TwainStateException(State, allowedMinimum, allowedMaximum, group, dataArgumentType, message,
- string.Format("TWAIN state {0} does not match required range {1}-{2} for operation {3}-{4}-{5}.",
- State, allowedMinimum, allowedMaximum, group, dataArgumentType, message));
- }
+ Debug.WriteLine("TWAIN State = " + newState);
+ State = newState;
+ if (notifyChange) { RaisePropertyChanged("State"); }
+ }
+ ICommitable ITwainSessionInternal.GetPendingStateChanger(int newState)
+ {
+ return new TentativeStateChanger(this, newState);
}
- #endregion
- #region state transition calls
HandleRef _parentHandle;
///
@@ -815,40 +793,25 @@ namespace NTwain
#region nested stuff
- ///
- /// Gets the pending state changer and tentatively changes the session state to the specified value.
- /// Value will only stick if committed.
- ///
- /// The state.
- ///
- internal ICommitable GetPendingStateChanger(int state)
- {
- return new TentativeStateChanger(this, state);
- }
-
- internal interface ICommitable : IDisposable
- {
- void Commit();
- }
class TentativeStateChanger : ICommitable
{
bool _commit;
- TwainSession _session;
+ ITwainSessionInternal _session;
int _origState;
int _newState;
- public TentativeStateChanger(TwainSession session, int newState)
+ public TentativeStateChanger(ITwainSessionInternal session, int newState)
{
_session = session;
_origState = session.State;
_newState = newState;
- _session._state = newState;
+ _session.ChangeState(newState, false);
}
public void Commit()
{
if (_session.State == _newState)
{
- _session.State = _session.State;
+ _session.ChangeState(_newState, true);
}
_commit = true;
}
@@ -859,7 +822,7 @@ namespace NTwain
{
if (!_commit && _session.State == _newState)
{
- _session._state = _origState;
+ _session.ChangeState(_origState, false);
}
}
diff --git a/NTwain/TwainSessionExtensions.cs b/NTwain/TwainSessionExtensions.cs
index 6bd7831..b133b74 100644
--- a/NTwain/TwainSessionExtensions.cs
+++ b/NTwain/TwainSessionExtensions.cs
@@ -62,6 +62,28 @@ namespace NTwain
return list;
}
+ ///
+ /// Verifies the session is within the specified state range (inclusive). Throws
+ /// if violated.
+ ///
+ /// The session.
+ /// The allowed minimum.
+ /// The allowed maximum.
+ /// The triplet data group.
+ /// The triplet data argument type.
+ /// The triplet message.
+ ///
+ internal static void VerifyState(this ITwainSessionInternal session, int allowedMinimum, int allowedMaximum, DataGroups group, DataArgumentType dataArgumentType, NTwain.Values.Message message)
+ {
+ if (session.EnforceState && (session.State < allowedMinimum || session.State > allowedMaximum))
+ {
+ throw new TwainStateException(session.State, allowedMinimum, allowedMaximum, group, dataArgumentType, message,
+ string.Format("TWAIN state {0} does not match required range {1}-{2} for operation {3}-{4}-{5}.",
+ session.State, allowedMinimum, allowedMaximum, group, dataArgumentType, message));
+ }
+ }
+
+
#region common caps
///
diff --git a/Tests/NTwain.Tests/TwainSessionTests.cs b/Tests/NTwain.Tests/TwainSessionTests.cs
index e36c2e5..6cd38b6 100644
--- a/Tests/NTwain.Tests/TwainSessionTests.cs
+++ b/Tests/NTwain.Tests/TwainSessionTests.cs
@@ -12,9 +12,9 @@ namespace NTwain.Tests
[ExpectedException(typeof(TwainStateException), "State check failed to throw.")]
public void VerifyState_Throws_When_State_Is_Enforced()
{
- TwainSession session = new TwainSession(TWIdentity.Create(DataGroups.Image, new Version(1, 0), "test", "test", "test", "test"));
+ ITwainSessionInternal session = new TwainSession(TWIdentity.Create(DataGroups.Image, new Version(1, 0), "test", "test", "test", "test"));
session.EnforceState = true;
- session.State = 4;
+ session.ChangeState(4, false);
session.VerifyState(6, 6, DataGroups.Image, DataArgumentType.ImageNativeXfer, Message.Get);
}
@@ -22,9 +22,9 @@ namespace NTwain.Tests
[TestMethod]
public void VerifyState_No_Throws_When_State_Is_Not_Enforced()
{
- TwainSession session = new TwainSession(TWIdentity.Create(DataGroups.Image, new Version(1, 0), "test", "test", "test", "test"));
+ ITwainSessionInternal session = new TwainSession(TWIdentity.Create(DataGroups.Image, new Version(1, 0), "test", "test", "test", "test"));
session.EnforceState = false;
- session.State = 4;
+ session.ChangeState(4, false);
session.VerifyState(6, 6, DataGroups.Image, DataArgumentType.ImageNativeXfer, Message.Get);
}