diff --git a/NTwain/DataTransferredEventArgs.cs b/NTwain/DataTransferredEventArgs.cs
index 95f17f4..a6c3724 100644
--- a/NTwain/DataTransferredEventArgs.cs
+++ b/NTwain/DataTransferredEventArgs.cs
@@ -35,7 +35,7 @@ namespace NTwain
/// The memory data.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
- public byte[] MemData { get; internal set; }
+ public byte[] MemoryData { get; internal set; }
///
/// Gets the final image information if applicable.
diff --git a/NTwain/Internals/InternalMessageLoopHook.cs b/NTwain/Internals/InternalMessageLoopHook.cs
index 28379c8..6b622b9 100644
--- a/NTwain/Internals/InternalMessageLoopHook.cs
+++ b/NTwain/Internals/InternalMessageLoopHook.cs
@@ -9,7 +9,7 @@ using System.Windows.Threading;
namespace NTwain.Internals
{
- sealed class InternalMessageLoopHook : MessageLoopHook
+ sealed class InternalMessageLoopHook : MessageLoopHook
{
Dispatcher _dispatcher;
WindowsHook _hook;
@@ -55,14 +55,14 @@ namespace NTwain.Internals
}
}
- internal override void BeginInvoke(Action action)
+ public override void BeginInvoke(Action action)
{
if (_dispatcher == null) { throw new InvalidOperationException(Resources.MsgLoopUnavailble); }
_dispatcher.BeginInvoke(DispatcherPriority.Normal, action);
}
- internal override void Invoke(Action action)
+ public override void Invoke(Action action)
{
if (_dispatcher == null) { throw new InvalidOperationException(Resources.MsgLoopUnavailble); }
diff --git a/NTwain/Internals/MESSAGE.cs b/NTwain/Internals/MESSAGE.cs
index 7a04c7c..1facde2 100644
--- a/NTwain/Internals/MESSAGE.cs
+++ b/NTwain/Internals/MESSAGE.cs
@@ -12,7 +12,7 @@ namespace NTwain.Internals
/// The MSG structure in Windows for TWAIN use.
///
[StructLayout(LayoutKind.Sequential)]
- public struct MESSAGE
+ struct MESSAGE
{
public MESSAGE(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam)
{
diff --git a/NTwain/Internals/TransferLogic.cs b/NTwain/Internals/TransferLogic.cs
index acff1bb..8ce7b62 100644
--- a/NTwain/Internals/TransferLogic.cs
+++ b/NTwain/Internals/TransferLogic.cs
@@ -118,9 +118,9 @@ namespace NTwain.Internals
} while (rc == ReturnCode.Success && pending.Count != 0);
- // some poorly written scanner drivers return failure on EndXfer so also check for pending count now
+ // some poorly written scanner drivers return failure on EndXfer so also check for pending count now.
// this may break with other sources but we'll see
- if (pending.Count == 0)
+ if (pending.Count == 0 && session.State > 5)
{
session.ChangeState(5, true);
session.DisableSource();
@@ -441,7 +441,7 @@ namespace NTwain.Internals
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs
{
NativeData = dataPtr,
- MemData = dataArray,
+ MemoryData = dataArray,
FileDataPath = filePath,
ImageInfo = imgInfo,
//ExImageInfo = extInfo
diff --git a/NTwain/MessageLoopHooks.cs b/NTwain/MessageLoopHooks.cs
index 449942c..fd3fcd5 100644
--- a/NTwain/MessageLoopHooks.cs
+++ b/NTwain/MessageLoopHooks.cs
@@ -16,7 +16,11 @@ namespace NTwain
internal abstract void Start(IWinMessageFilter filter);
internal abstract void Stop();
- internal virtual void BeginInvoke(Action action)
+ ///
+ /// Asynchronously invokes the specified action on the message loop thread.
+ ///
+ /// The action.
+ public virtual void BeginInvoke(Action action)
{
if (SyncContext == null)
{
@@ -30,7 +34,12 @@ namespace NTwain
}, null);
}
}
- internal virtual void Invoke(Action action)
+
+ ///
+ /// Synchronously invokes the specified action on the message loop thread.
+ ///
+ /// The action.
+ public virtual void Invoke(Action action)
{
if (SyncContext == null)
{
@@ -63,11 +72,11 @@ namespace NTwain
///
/// Initializes a new instance of the class.
///
- /// The handle to the app window.
+ /// The handle to the app window.
/// A valid window handle is required.
- public WindowsFormsMessageLoopHook(IntPtr hwnd)
+ public WindowsFormsMessageLoopHook(IntPtr windowHandle)
{
- if (hwnd == IntPtr.Zero) { throw new ArgumentException("A valid window handle is required."); }
+ if (windowHandle == IntPtr.Zero) { throw new ArgumentException("A valid window handle is required."); }
if (!System.Windows.Forms.Application.MessageLoop)
{
@@ -78,7 +87,7 @@ namespace NTwain
{
ThrowInvalidOp();
}
- Handle = hwnd;
+ Handle = windowHandle;
SyncContext = sync;
}
internal override string InvalidMessage
@@ -133,11 +142,11 @@ namespace NTwain
///
/// Initializes a new instance of the class.
///
- /// The handle to the app window.
+ /// The handle to the app window.
/// A valid window handle is required.
- public WpfMessageLoopHook(IntPtr hwnd)
+ public WpfMessageLoopHook(IntPtr windowHandle)
{
- if (hwnd == IntPtr.Zero) { throw new ArgumentException("A valid window handle is required."); }
+ if (windowHandle == IntPtr.Zero) { throw new ArgumentException("A valid window handle is required."); }
if (System.Windows.Application.Current == null ||
!System.Windows.Application.Current.Dispatcher.CheckAccess())
@@ -149,7 +158,7 @@ namespace NTwain
{
ThrowInvalidOp();
}
- Handle = hwnd;
+ Handle = windowHandle;
SyncContext = sync;
}
internal override string InvalidMessage
diff --git a/NTwain/Properties/VersionInfo.cs b/NTwain/Properties/VersionInfo.cs
index 2f2ce7b..36dcc5a 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 = "2.0.0.0";
// change this for each nuget release
- public const string Build = "2.0.3";
+ public const string Build = "2.0.6";
}
}
\ No newline at end of file
diff --git a/NTwain/Triplets/DGControl/DGControl.CapabilityCustom.cs b/NTwain/Triplets/DGControl/DGControl.CapabilityCustom.cs
index 5f7d41c..1e5f2f4 100644
--- a/NTwain/Triplets/DGControl/DGControl.CapabilityCustom.cs
+++ b/NTwain/Triplets/DGControl/DGControl.CapabilityCustom.cs
@@ -16,6 +16,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode Get(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 7, DataGroups.Control, (DataArgumentType)customDAT, Message.Get);
@@ -28,6 +29,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode GetCurrent(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 7, DataGroups.Control, (DataArgumentType)customDAT, Message.GetCurrent);
@@ -40,6 +42,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode GetDefault(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 7, DataGroups.Control, (DataArgumentType)customDAT, Message.GetDefault);
@@ -53,6 +56,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode GetHelp(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 4, DataGroups.Control, (DataArgumentType)customDAT, Message.GetHelp);
@@ -66,6 +70,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode GetLabel(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 4, DataGroups.Control, (DataArgumentType)customDAT, Message.GetLabel);
@@ -79,6 +84,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode GetLabelEnum(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 4, DataGroups.Control, (DataArgumentType)customDAT, Message.GetLabelEnum);
@@ -91,6 +97,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode QuerySupport(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 7, DataGroups.Control, (DataArgumentType)customDAT, Message.QuerySupport);
@@ -104,6 +111,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode Reset(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 4, DataGroups.Control, (DataArgumentType)customDAT, Message.Reset);
@@ -117,6 +125,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode ResetAll(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 4, DataGroups.Control, (DataArgumentType)customDAT, Message.ResetAll);
@@ -133,6 +142,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode Set(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 6, DataGroups.Control, (DataArgumentType)customDAT, Message.Set);
@@ -148,6 +158,7 @@ namespace NTwain.Triplets
/// The custom DAT_* value from manufacturer.
/// The capability.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "DAT")]
public ReturnCode SetConstraint(ushort customDAT, TWCapability capability)
{
Session.VerifyState(4, 7, DataGroups.Control, (DataArgumentType)customDAT, Message.SetConstraint);
diff --git a/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs b/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs
index 296c21f..62dac5b 100644
--- a/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs
+++ b/NTwain/Triplets/DGControl/DGControl.SetupFileXfer.cs
@@ -16,7 +16,7 @@ namespace NTwain.Triplets
///
/// The setup file xfer.
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xfer"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
public ReturnCode Get(out TWSetupFileXfer setupFileXfer)
{
Session.VerifyState(4, 6, DataGroups.Control, DataArgumentType.SetupFileXfer, Message.Get);
@@ -29,7 +29,7 @@ namespace NTwain.Triplets
///
/// The setup file xfer.
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xfer"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
public ReturnCode GetDefault(out TWSetupFileXfer setupFileXfer)
{
Session.VerifyState(4, 6, DataGroups.Control, DataArgumentType.SetupFileXfer, Message.GetDefault);
@@ -43,7 +43,7 @@ namespace NTwain.Triplets
///
/// The setup file xfer.
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xfer"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
public ReturnCode Reset(out TWSetupFileXfer setupFileXfer)
{
Session.VerifyState(4, 4, DataGroups.Control, DataArgumentType.SetupFileXfer, Message.Reset);
@@ -60,7 +60,8 @@ namespace NTwain.Triplets
///
/// The setup file xfer.
///
- public ReturnCode Set(TWSetupFileXfer setupFileXfer)
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xfer")]
+ public ReturnCode Set(TWSetupFileXfer setupFileXfer)
{
Session.VerifyState(4, 6, DataGroups.Control, DataArgumentType.SetupFileXfer, Message.Set);
return Dsm.DsmEntry(Session.AppId, Session.CurrentSource.Identity, Message.Set, setupFileXfer);
diff --git a/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs b/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs
index 6c30f10..900d0a8 100644
--- a/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs
+++ b/NTwain/Triplets/DGControl/DGControl.SetupMemXfer.cs
@@ -6,7 +6,7 @@ namespace NTwain.Triplets
///
/// Represents .
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mem")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xfer"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mem")]
public sealed class SetupMemXfer : OpBase
{
internal SetupMemXfer(ITwainSessionInternal session) : base(session) { }
@@ -16,7 +16,7 @@ namespace NTwain.Triplets
///
/// The setup mem xfer.
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mem"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xfer"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
public ReturnCode Get(out TWSetupMemXfer setupMemXfer)
{
Session.VerifyState(4, 6, DataGroups.Control, DataArgumentType.SetupMemXfer, Message.Get);
diff --git a/NTwain/Triplets/DGControl/DGControl.XferGroup.cs b/NTwain/Triplets/DGControl/DGControl.XferGroup.cs
index 181298f..25209d8 100644
--- a/NTwain/Triplets/DGControl/DGControl.XferGroup.cs
+++ b/NTwain/Triplets/DGControl/DGControl.XferGroup.cs
@@ -6,7 +6,8 @@ namespace NTwain.Triplets
///
/// Represents .
///
- public sealed class XferGroup : OpBase
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xfer")]
+ public sealed class XferGroup : OpBase
{
internal XferGroup(ITwainSessionInternal session) : base(session) { }
diff --git a/NTwain/Triplets/DGCustom.cs b/NTwain/Triplets/DGCustom.cs
index 2aef0bd..1d5d320 100644
--- a/NTwain/Triplets/DGCustom.cs
+++ b/NTwain/Triplets/DGCustom.cs
@@ -28,6 +28,7 @@ namespace NTwain.Triplets
/// The message.
/// The data.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "3#"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dat"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dsm")]
public ReturnCode DsmEntry(
DataGroups group,
DataArgumentType dat,
diff --git a/NTwain/Triplets/DGImage/DGImage.CieColor.cs b/NTwain/Triplets/DGImage/DGImage.CieColor.cs
index 5b173cf..cdd687b 100644
--- a/NTwain/Triplets/DGImage/DGImage.CieColor.cs
+++ b/NTwain/Triplets/DGImage/DGImage.CieColor.cs
@@ -6,7 +6,8 @@ namespace NTwain.Triplets
///
/// Represents .
///
- public sealed class CieColor : OpBase
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cie")]
+ public sealed class CieColor : OpBase
{
internal CieColor(ITwainSessionInternal session) : base(session) { }
@@ -16,7 +17,7 @@ namespace NTwain.Triplets
///
/// Color data.
///
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "cie"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
public ReturnCode Get(out TWCieColor cieColor)
{
Session.VerifyState(4, 6, DataGroups.Image, DataArgumentType.CieColor, Message.Get);
diff --git a/NTwain/Triplets/DGImage/DGImage.IccProfile.cs b/NTwain/Triplets/DGImage/DGImage.IccProfile.cs
index 78e9250..87249a8 100644
--- a/NTwain/Triplets/DGImage/DGImage.IccProfile.cs
+++ b/NTwain/Triplets/DGImage/DGImage.IccProfile.cs
@@ -6,7 +6,8 @@ namespace NTwain.Triplets
///
/// Represents .
///
- public sealed class IccProfile : OpBase
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Icc")]
+ public sealed class IccProfile : OpBase
{
internal IccProfile(ITwainSessionInternal session) : base(session) { }
diff --git a/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs b/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs
index 62abc97..8a7b8fb 100644
--- a/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs
+++ b/NTwain/Triplets/DGImage/DGImage.RgbResponse.cs
@@ -6,7 +6,8 @@ namespace NTwain.Triplets
///
/// Represents .
///
- public sealed class RgbResponse : OpBase
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rgb")]
+ public sealed class RgbResponse : OpBase
{
internal RgbResponse(ITwainSessionInternal session) : base(session) { }
diff --git a/NTwain/Triplets/DGImage/DGImage.cs b/NTwain/Triplets/DGImage/DGImage.cs
index 734fe37..339b834 100644
--- a/NTwain/Triplets/DGImage/DGImage.cs
+++ b/NTwain/Triplets/DGImage/DGImage.cs
@@ -19,6 +19,7 @@ namespace NTwain.Triplets
///
/// Gets the operations defined for DAT_CIECOLOR.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cie")]
public CieColor CieColor
{
get
@@ -73,6 +74,7 @@ namespace NTwain.Triplets
///
/// Gets the operations defined for DAT_ICCPROFILE.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Icc")]
public IccProfile IccProfile
{
get
@@ -175,6 +177,7 @@ namespace NTwain.Triplets
///
/// Gets the operations defined for DAT_RGBRESPONSE.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rgb")]
public RgbResponse RgbResponse
{
get
diff --git a/NTwain/TwainSession.cs b/NTwain/TwainSession.cs
index a1c5a60..0571ed2 100644
--- a/NTwain/TwainSession.cs
+++ b/NTwain/TwainSession.cs
@@ -41,7 +41,10 @@ namespace NTwain
_appId = appId;
((ITwainSessionInternal)this).ChangeState(1, false);
+#if DEBUG
+ // defaults to false on release since it's only useful during dev
EnforceState = true;
+#endif
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
@@ -54,12 +57,18 @@ namespace NTwain
internal static TwainSource GetSourceInstance(ITwainSessionInternal session, TWIdentity sourceId)
{
+ TwainSource source = null;
var key = string.Format(CultureInfo.InvariantCulture, "{0}|{1}|{2}", sourceId.Manufacturer, sourceId.ProductFamily, sourceId.ProductName);
if (__ownedSources.ContainsKey(key))
{
- return __ownedSources[key];
+ source = __ownedSources[key];
+ source.Session = session;
}
- return __ownedSources[key] = new TwainSource(session, sourceId);
+ else
+ {
+ __ownedSources[key] = source = new TwainSource(session, sourceId);
+ }
+ return source;
}
///
@@ -428,7 +437,7 @@ namespace NTwain
_msgLoopHook.Invoke(() =>
{
- Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: EnableSource.", Thread.CurrentThread.ManagedThreadId));
+ Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: EnableSource with {1}.", Thread.CurrentThread.ManagedThreadId, mode));
// app v2.2 or higher uses callback2
if (_appId.ProtocolMajor >= 2 && _appId.ProtocolMinor >= 2)
@@ -477,21 +486,32 @@ namespace NTwain
return rc;
}
+ bool _disabling;
ReturnCode ITwainSessionInternal.DisableSource()
{
var rc = ReturnCode.Failure;
-
- _msgLoopHook.Invoke(() =>
+ if (!_disabling) // temp hack as a workaround to this being called from multiple threads (xfer logic & closedsreq msg)
{
- Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: DisableSource.", Thread.CurrentThread.ManagedThreadId));
-
- rc = ((ITwainSessionInternal)this).DGControl.UserInterface.DisableDS(_twui);
- if (rc == ReturnCode.Success)
+ _disabling = true;
+ try
{
- _callbackObj = null;
- SafeAsyncSyncableRaiseOnEvent(OnSourceDisabled, SourceDisabled);
+ _msgLoopHook.Invoke(() =>
+ {
+ Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: DisableSource.", Thread.CurrentThread.ManagedThreadId));
+
+ rc = ((ITwainSessionInternal)this).DGControl.UserInterface.DisableDS(_twui);
+ if (rc == ReturnCode.Success)
+ {
+ _callbackObj = null;
+ SafeAsyncSyncableRaiseOnEvent(OnSourceDisabled, SourceDisabled);
+ }
+ });
}
- });
+ finally
+ {
+ _disabling = false;
+ }
+ }
return rc;
}
@@ -524,15 +544,15 @@ namespace NTwain
_msgLoopHook.Invoke(() =>
{
- if (targetState < 7)
+ if (targetState < 7 && CurrentSource != null)
{
((ITwainSessionInternal)this).DGControl.PendingXfers.EndXfer(new TWPendingXfers());
}
- if (targetState < 6)
+ if (targetState < 6 && CurrentSource != null)
{
((ITwainSessionInternal)this).DGControl.PendingXfers.Reset(new TWPendingXfers());
}
- if (targetState < 5)
+ if (targetState < 5 && CurrentSource != null)
{
((ITwainSessionInternal)this).DisableSource();
}
@@ -782,6 +802,7 @@ namespace NTwain
break;
case Message.CloseDSReq:
case Message.CloseDSOK:
+ Debug.WriteLine("Got msg " + msg);
// even though it says closeDS it's really disable.
// dsok is sent if source is enabled with uionly
diff --git a/NTwain/TwainSource.Caps.cs b/NTwain/TwainSource.Caps.cs
index 7b01ad1..3948aae 100644
--- a/NTwain/TwainSource.Caps.cs
+++ b/NTwain/TwainSource.Caps.cs
@@ -18,7 +18,7 @@ namespace NTwain
QuerySupport retVal = QuerySupport.None;
using (TWCapability cap = new TWCapability(capId))
{
- var rc = _session.DGControl.Capability.QuerySupport(cap);
+ var rc = Session.DGControl.Capability.QuerySupport(cap);
if (rc == ReturnCode.Success)
{
var read = CapabilityReader.ReadValue(cap);
@@ -41,7 +41,7 @@ namespace NTwain
{
using (TWCapability cap = new TWCapability(capId))
{
- var rc = _session.DGControl.Capability.GetCurrent(cap);
+ var rc = Session.DGControl.Capability.GetCurrent(cap);
if (rc == ReturnCode.Success)
{
var read = CapabilityReader.ReadValue(cap);
@@ -82,7 +82,7 @@ namespace NTwain
var list = new List
public partial class TwainSource
{
- ITwainSessionInternal _session;
+ internal ITwainSessionInternal Session { get; set; }
internal TwainSource(ITwainSessionInternal session, TWIdentity sourceId)
{
- _session = session;
+ Session = session;
Identity = sourceId;
}
@@ -32,11 +32,11 @@ namespace NTwain
public ReturnCode Open()
{
var rc = ReturnCode.Failure;
- _session.MessageLoopHook.Invoke(() =>
+ Session.MessageLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId));
- rc = _session.DGControl.Identity.OpenDS(this);
+ rc = Session.DGControl.Identity.OpenDS(this);
});
return rc;
}
@@ -48,11 +48,11 @@ namespace NTwain
public ReturnCode Close()
{
var rc = ReturnCode.Failure;
- _session.MessageLoopHook.Invoke(() =>
+ Session.MessageLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId));
- rc = _session.DGControl.Identity.CloseDS();
+ rc = Session.DGControl.Identity.CloseDS();
if (rc == ReturnCode.Success)
{
SupportedCaps = null;
@@ -71,7 +71,7 @@ namespace NTwain
///
public ReturnCode StartTransfer(SourceEnableMode mode, bool modal, IntPtr windowHandle)
{
- return _session.EnableSource(mode, modal, windowHandle);
+ return Session.EnableSource(mode, modal, windowHandle);
}
///
@@ -81,7 +81,7 @@ namespace NTwain
public TWStatus GetStatus()
{
TWStatus stat;
- _session.DGControl.Status.GetSource(out stat);
+ Session.DGControl.Status.GetSource(out stat);
return stat;
}
///
@@ -91,7 +91,7 @@ namespace NTwain
public TWStatusUtf8 GetStatusUtf8()
{
TWStatusUtf8 stat;
- _session.DGControl.StatusUtf8.GetSource(out stat);
+ Session.DGControl.StatusUtf8.GetSource(out stat);
return stat;
}
@@ -170,7 +170,7 @@ namespace NTwain
{
get
{
- if (_supportedCaps == null && _session.State > 3)
+ if (_supportedCaps == null && Session.State > 3)
{
_supportedCaps = CapGetValues(CapabilityId.CapSupportedCaps).CastToEnum(false);
}
@@ -191,7 +191,7 @@ namespace NTwain
{
get
{
- return _session.DGControl;
+ return Session.DGControl;
}
}
@@ -202,7 +202,7 @@ namespace NTwain
{
get
{
- return _session.DGImage;
+ return Session.DGImage;
}
}
@@ -213,7 +213,7 @@ namespace NTwain
{
get
{
- return _session.DGCustom;
+ return Session.DGCustom;
}
}
@@ -232,7 +232,7 @@ namespace NTwain
///// Name of the property.
//protected void OnPropertyChanged(string propertyName)
//{
- // var syncer = _session.SynchronizationContext;
+ // var syncer = Session.SynchronizationContext;
// if (syncer == null)
// {
// try
diff --git a/Tests/Tester.WPF/App.xaml b/Tests/Tester.WPF/App.xaml
index d733b8c..9ea9427 100644
--- a/Tests/Tester.WPF/App.xaml
+++ b/Tests/Tester.WPF/App.xaml
@@ -1,7 +1,7 @@
+ StartupUri="Dummy.xaml">
diff --git a/Tests/Tester.WPF/Dummy.xaml b/Tests/Tester.WPF/Dummy.xaml
new file mode 100644
index 0000000..9304408
--- /dev/null
+++ b/Tests/Tester.WPF/Dummy.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/Tests/Tester.WPF/Dummy.xaml.cs b/Tests/Tester.WPF/Dummy.xaml.cs
new file mode 100644
index 0000000..8c055a9
--- /dev/null
+++ b/Tests/Tester.WPF/Dummy.xaml.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace Tester.WPF
+{
+ ///
+ /// Interaction logic for Dummy.xaml
+ ///
+ public partial class Dummy : Window
+ {
+ public Dummy()
+ {
+ InitializeComponent();
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ new MainWindow().ShowDialog();
+ }
+ }
+}
diff --git a/Tests/Tester.WPF/MainWindow.xaml.cs b/Tests/Tester.WPF/MainWindow.xaml.cs
index 72a3198..c5b167b 100644
--- a/Tests/Tester.WPF/MainWindow.xaml.cs
+++ b/Tests/Tester.WPF/MainWindow.xaml.cs
@@ -4,6 +4,7 @@ using NTwain;
using NTwain.Data;
using System;
using System.ComponentModel;
+using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
@@ -51,13 +52,18 @@ namespace Tester.WPF
});
}
}
-
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ e.Cancel = _twainVM.State > 4;
+ base.OnClosing(e);
+ }
protected override void OnClosed(EventArgs e)
{
if (_twainVM.State == 4)
{
_twainVM.CurrentSource.Close();
}
+ _twainVM.Close();
base.OnClosed(e);
}
@@ -68,6 +74,8 @@ namespace Tester.WPF
// use this for internal msg loop
//var rc = _twainVM.Open();
// use this to hook into current app loop
+
+
var rc = _twainVM.Open(new WpfMessageLoopHook(new WindowInteropHelper(this).Handle));
if (rc == ReturnCode.Success)
@@ -82,6 +90,15 @@ namespace Tester.WPF
private void SrcList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
+
+ //var test = new NTwain.Internals.InternalMessageLoopHook();
+ //test.StartTest();
+ //test.BeginInvoke(() =>
+ //{
+ // Debug.WriteLine("doodle");
+ // test.StopTest();
+ //});
+
if (_twainVM.State == 4)
{
_twainVM.CurrentSource.Close();
diff --git a/Tests/Tester.WPF/Tester.WPF.csproj b/Tests/Tester.WPF/Tester.WPF.csproj
index b7b2cd3..54e4e0b 100644
--- a/Tests/Tester.WPF/Tester.WPF.csproj
+++ b/Tests/Tester.WPF/Tester.WPF.csproj
@@ -80,7 +80,14 @@
MSBuild:Compile
Designer
+
+ Dummy.xaml
+
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
diff --git a/Tests/Tester.WPF/ViewModels/TwainVM.cs b/Tests/Tester.WPF/ViewModels/TwainVM.cs
index 8153351..51ece2a 100644
--- a/Tests/Tester.WPF/ViewModels/TwainVM.cs
+++ b/Tests/Tester.WPF/ViewModels/TwainVM.cs
@@ -3,6 +3,7 @@ using GalaSoft.MvvmLight.Messaging;
using NTwain;
using NTwain.Data;
using System;
+using System.IO;
using System.Reflection;
using System.Threading;
using System.Windows.Media;
@@ -76,12 +77,23 @@ namespace Tester.WPF
var fileSetup = new TWSetupFileXfer
{
Format = wantFormat,
- FileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.tif")
+ FileName = GetUniqueName(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test", ".tif")
};
var rc = this.CurrentSource.DGControl.SetupFileXfer.Set(fileSetup);
}
}
+ private string GetUniqueName(string dir, string name, string ext)
+ {
+ var filePath = Path.Combine(dir, name + ext);
+ int next = 1;
+ while (File.Exists(filePath))
+ {
+ filePath = Path.Combine(dir, string.Format("{0} ({1}){2}", name, next++, ext));
+ }
+ return filePath;
+ }
+
protected override void OnDataTransferred(DataTransferredEventArgs e)
{
ImageSource img = null;
diff --git a/Tests/Tester.Winform/TestForm.cs b/Tests/Tester.Winform/TestForm.cs
index bebe5f1..dad7dbb 100644
--- a/Tests/Tester.Winform/TestForm.cs
+++ b/Tests/Tester.Winform/TestForm.cs
@@ -41,13 +41,16 @@ namespace Tester.Winform
protected override void OnFormClosing(FormClosingEventArgs e)
{
- if (e.CloseReason == CloseReason.UserClosing && _twain.State > 4)
+ if (_twain != null)
{
- e.Cancel = true;
- }
- else
- {
- CleanupTwain();
+ if (e.CloseReason == CloseReason.UserClosing && _twain.State > 4)
+ {
+ e.Cancel = true;
+ }
+ else
+ {
+ CleanupTwain();
+ }
}
base.OnFormClosing(e);
}
@@ -105,22 +108,19 @@ namespace Tester.Winform
private void CleanupTwain()
{
- if (_twain != null)
+ if (_twain.State == 4)
{
- if (_twain.State == 4)
- {
- _twain.CurrentSource.Close();
- }
- if (_twain.State == 3)
- {
- _twain.Close();
- }
+ _twain.CurrentSource.Close();
+ }
+ if (_twain.State == 3)
+ {
+ _twain.Close();
+ }
- if (_twain.State > 2)
- {
- // normal close down didn't work, do hard kill
- _twain.ForceStepDown(2);
- }
+ if (_twain.State > 2)
+ {
+ // normal close down didn't work, do hard kill
+ _twain.ForceStepDown(2);
}
}
@@ -245,7 +245,7 @@ namespace Tester.Winform
// use this for internal msg loop
_twain.Open();
// use this to hook into current app loop
- //_twain.Open(new WinformMessageLoopHook(this.Handle));
+ //_twain.Open(new WindowsFormsMessageLoopHook(this.Handle));
}
if (_twain.State >= 3)