diff --git a/NTwain.Net35/NTwain.Net35.csproj b/NTwain.Net35/NTwain.Net35.csproj index efb9329..fb23ed6 100644 --- a/NTwain.Net35/NTwain.Net35.csproj +++ b/NTwain.Net35/NTwain.Net35.csproj @@ -43,15 +43,12 @@ + + CapabilityReadout.cs + DataTransferredEventArgs.cs - - Data\CapReadOut.cs - - - Data\SourceEnableMode.cs - Data\TwainTypes.cs @@ -64,8 +61,8 @@ Data\TypeReader.cs - - Data\ValueConverter.cs + + Data\ValueExtensions.cs DeviceEventArgs.cs @@ -109,9 +106,6 @@ ITwainSession.cs - - ITwainState.cs - Platform.cs @@ -127,6 +121,9 @@ Properties\VersionInfo.cs + + SourceEnableMode.cs + TransferErrorEventArgs.cs diff --git a/NTwain.sln b/NTwain.sln index 1d94121..8595d8e 100644 --- a/NTwain.sln +++ b/NTwain.sln @@ -16,7 +16,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Others", "Others", "{4CE0B9ED-2CD1-440F-B4EC-35ECA6D61EFE}" ProjectSection(SolutionItems) = preProject LICENSE.txt = LICENSE.txt - README.markdown = README.markdown + README.md = README.md Spec\twain2.3.h = Spec\twain2.3.h EndProjectSection EndProject diff --git a/NTwain/Data/CapReadOut.cs b/NTwain/CapabilityReadOut.cs similarity index 92% rename from NTwain/Data/CapReadOut.cs rename to NTwain/CapabilityReadOut.cs index 833e760..a5683c0 100644 --- a/NTwain/Data/CapReadOut.cs +++ b/NTwain/CapabilityReadOut.cs @@ -1,16 +1,17 @@ -using NTwain.Properties; +using NTwain.Data; +using NTwain.Properties; using System; using System.Collections.Generic; using System.Globalization; using System.Runtime.InteropServices; -namespace NTwain.Data +namespace NTwain { /// /// The one-stop class for reading TWAIN cap values. /// This contains all the properties for the 4 container types. /// - public class CapReadOut + public class CapabilityReadOut { /// /// Reads the value from a that was returned @@ -24,7 +25,7 @@ namespace NTwain.Data /// or /// capability /// - public static CapReadOut ReadValue(TWCapability capability) + public static CapabilityReadOut ReadValue(TWCapability capability) { if (capability == null) { throw new ArgumentNullException("capability"); } if (capability.Container == IntPtr.Zero) { throw new ArgumentException(Resources.CapHasNoData, "capability"); } @@ -36,22 +37,22 @@ namespace NTwain.Data switch (capability.ContainerType) { case ContainerType.Array: - return new CapReadOut + return new CapabilityReadOut { ContainerType = capability.ContainerType, }.ReadArrayValue(baseAddr); case ContainerType.Enum: - return new CapReadOut + return new CapabilityReadOut { ContainerType = capability.ContainerType, }.ReadEnumValue(baseAddr); case ContainerType.OneValue: - return new CapReadOut + return new CapabilityReadOut { ContainerType = capability.ContainerType, }.ReadOneValue(baseAddr); case ContainerType.Range: - return new CapReadOut + return new CapabilityReadOut { ContainerType = capability.ContainerType, }.ReadRangeValue(baseAddr); @@ -160,7 +161,7 @@ namespace NTwain.Data #region reader methods - CapReadOut ReadOneValue(IntPtr baseAddr) + CapabilityReadOut ReadOneValue(IntPtr baseAddr) { int offset = 0; ItemType = (ItemType)(ushort)Marshal.ReadInt16(baseAddr, offset); @@ -169,7 +170,7 @@ namespace NTwain.Data return this; } - CapReadOut ReadArrayValue(IntPtr baseAddr) + CapabilityReadOut ReadArrayValue(IntPtr baseAddr) { int offset = 0; ItemType = (ItemType)(ushort)Marshal.ReadInt16(baseAddr, offset); @@ -187,7 +188,7 @@ namespace NTwain.Data return this; } - CapReadOut ReadEnumValue(IntPtr baseAddr) + CapabilityReadOut ReadEnumValue(IntPtr baseAddr) { int offset = 0; ItemType = (ItemType)(ushort)Marshal.ReadInt16(baseAddr, offset); @@ -209,7 +210,7 @@ namespace NTwain.Data return this; } - CapReadOut ReadRangeValue(IntPtr baseAddr) + CapabilityReadOut ReadRangeValue(IntPtr baseAddr) { int offset = 0; ItemType = (ItemType)(ushort)Marshal.ReadInt16(baseAddr, offset); diff --git a/NTwain/Data/TwainTypesExtended.cs b/NTwain/Data/TwainTypesExtended.cs index 22e9ef5..925097d 100644 --- a/NTwain/Data/TwainTypesExtended.cs +++ b/NTwain/Data/TwainTypesExtended.cs @@ -486,10 +486,12 @@ namespace NTwain.Data /// /// Channel-specific transform parameters. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWDecodeFunction[] Decode { get { return _decode; } }//set { _decode = value; } } /// /// Flattened 3x3 matrix that specifies how channels are mixed in. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWFix32[] Mix { get { return _mix; } }//set { _mix = value; } } /// @@ -527,6 +529,7 @@ namespace NTwain.Data /// /// Array of ItemType values starts here. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public object[] ItemList { get { return _itemList; } @@ -1060,6 +1063,7 @@ namespace NTwain.Data /// Optional table look-up values used by the decode function. Samples /// are ordered sequentially and end-to-end as A, B, C, L, M, and N. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWFix32[] Samples { get { return _samples; } } } @@ -1251,6 +1255,7 @@ namespace NTwain.Data /// /// The enumerated list: one value resides within each array element. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public object[] ItemList { get { return _itemList; } @@ -1352,6 +1357,7 @@ namespace NTwain.Data /// /// Array of information. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWInfo[] Info { get { return _info; } } #region IDisposable Members @@ -1493,6 +1499,7 @@ namespace NTwain.Data /// Transfer curve descriptors. All three channels (Channel1, Channel2 /// and Channel3) must contain the same value for every entry. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWElement8[] Response { get { return _response; } set { _response = value; } } } @@ -1772,6 +1779,7 @@ namespace NTwain.Data /// bits. However, both the application and Source must simultaneously /// support sample sizes greater than 8 bits per color. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public short[] BitsPerSample { get { return _bitsPerSample; } } /// /// The number of bits in each image pixel (or bit depth). This value is @@ -1969,23 +1977,28 @@ namespace NTwain.Data /// /// Mapping of components to Quantization tables. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public ushort[] QuantMap { get { return _quantMap; } set { _quantMap = value; } } /// /// Quantization tables. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWMemory[] QuantTable { get { return _quantTable; } set { _quantTable = value; } } /// /// Mapping of components to Huffman tables. Null entries signify /// selection of the default tables. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public ushort[] HuffmanMap { get { return _huffmanMap; } set { _huffmanMap = value; } } /// /// DC Huffman tables. Null entries signify selection of the default tables. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWMemory[] HuffmanDC { get { return _huffmanDC; } set { _huffmanDC = value; } } /// /// AC Huffman tables. Null entries signify selection of the default tables. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWMemory[] HuffmanAC { get { return _huffmanAC; } set { _huffmanAC = value; } } } @@ -2023,6 +2036,7 @@ namespace NTwain.Data /// /// Array of palette values. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWElement8[] Colors { get { return _colors; } set { _colors = value; } } } @@ -2134,6 +2148,7 @@ namespace NTwain.Data /// Transfer curve descriptors. To minimize color shift problems, writing the /// same values into each channel is desirable. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public TWElement8[] Response { get { return _response; } set { _response = value; } } } diff --git a/NTwain/Data/TypeReader.cs b/NTwain/Data/TypeReader.cs index cf013c8..44ae557 100644 --- a/NTwain/Data/TypeReader.cs +++ b/NTwain/Data/TypeReader.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; namespace NTwain.Data @@ -67,7 +68,7 @@ namespace NTwain.Data val = ReadString(baseAddress, offset, TwainConst.String64 - 2); break; case ItemType.Handle: - val = new IntPtr(baseAddress.ToInt64() + offset); + val = Marshal.ReadIntPtr(baseAddress, offset); break; } offset += GetItemTypeSize(type); @@ -93,6 +94,28 @@ namespace NTwain.Data //return sb.ToString(); } + static readonly Dictionary __sizes = GenerateSizes(); + + private static Dictionary GenerateSizes() + { + var sizes = new Dictionary(); + sizes[ItemType.Int8] = 1; + sizes[ItemType.UInt8] = 1; + sizes[ItemType.Int16] = 2; + sizes[ItemType.UInt16] = 2; + sizes[ItemType.Bool] = 2; + sizes[ItemType.Int32] = 4; + sizes[ItemType.UInt32] = 4; + sizes[ItemType.Fix32] = 4; + sizes[ItemType.Frame] = 16; + sizes[ItemType.String32] = TwainConst.String32; + sizes[ItemType.String64] = TwainConst.String64; + sizes[ItemType.String128] = TwainConst.String128; + sizes[ItemType.String255] = TwainConst.String255; + sizes[ItemType.Handle] = IntPtr.Size; + + return sizes; + } /// /// Gets the byte size of the item type. @@ -101,31 +124,9 @@ namespace NTwain.Data /// public static int GetItemTypeSize(ItemType type) { - switch (type) + if (__sizes.ContainsKey(type)) { - case ItemType.Int8: - case ItemType.UInt8: - return 1; - case ItemType.UInt16: - case ItemType.Int16: - case ItemType.Bool: - return 2; - case ItemType.Int32: - case ItemType.UInt32: - case ItemType.Fix32: - return 4; - case ItemType.Frame: - return 16; - case ItemType.String32: - return TwainConst.String32; - case ItemType.String64: - return TwainConst.String64; - case ItemType.String128: - return TwainConst.String128; - case ItemType.String255: - return TwainConst.String255; - case ItemType.Handle: - return IntPtr.Size; + return __sizes[type]; } return 0; } diff --git a/NTwain/Data/ValueConverter.cs b/NTwain/Data/ValueExtensions.cs similarity index 50% rename from NTwain/Data/ValueConverter.cs rename to NTwain/Data/ValueExtensions.cs index f73a6dc..ad3ce82 100644 --- a/NTwain/Data/ValueConverter.cs +++ b/NTwain/Data/ValueExtensions.cs @@ -8,24 +8,50 @@ namespace NTwain.Data /// /// Utility on converting (possibly bad) integer values to enum values. /// - public static class ValueConverter + public static class ValueExtensions { - public static IList CastToEnum(this IEnumerable list) where T : struct,IConvertible + /// + /// Casts a list of objects to a list of specified enum. + /// + /// The type of the enum. + /// The list. + /// + public static IList CastToEnum(this IEnumerable list) where TEnum : struct,IConvertible { - return list.CastToEnum(true); + return list.CastToEnum(true); } - public static IList CastToEnum(this IEnumerable list, bool tryUpperWord) where T : struct,IConvertible + /// + /// Casts a list of objects to a list of specified enum. + /// + /// The type of the enum. + /// The list. + /// set to true for working with bad values. + /// + public static IList CastToEnum(this IEnumerable list, bool tryUpperWord) where TEnum : struct,IConvertible { - return list.Select(o => o.ConvertToEnum(tryUpperWord)).ToList(); + return list.Select(o => o.ConvertToEnum(tryUpperWord)).ToList(); } - public static T ConvertToEnum(this object value) where T : struct,IConvertible + /// + /// Casts an objects to the specified enum. + /// + /// The type of the enum. + /// The value. + /// + public static TEnum ConvertToEnum(this object value) where TEnum : struct,IConvertible { - return ConvertToEnum(value, true); + return ConvertToEnum(value, true); } - public static T ConvertToEnum(this object value, bool tryUpperWord) where T : struct,IConvertible + /// + /// Casts an objects to the specified enum. + /// + /// The type of the enum. + /// The value. + /// if set to true [try upper word]. + /// + public static TEnum ConvertToEnum(this object value, bool tryUpperWord) where TEnum : struct,IConvertible { - var returnType = typeof(T); + var returnType = typeof(TEnum); // standard int values if (returnType.IsEnum) @@ -41,22 +67,22 @@ namespace NTwain.Data var enumVal = GetLowerWord(intVal); if (!Enum.IsDefined(returnType, enumVal)) { - return (T)Enum.ToObject(returnType, GetUpperWord(intVal)); + return (TEnum)Enum.ToObject(returnType, GetUpperWord(intVal)); } } } // this may work better? - return (T)Enum.ToObject(returnType, value); + return (TEnum)Enum.ToObject(returnType, value); //// cast to underlying type first then to the enum //return (T)Convert.ChangeType(value, rawType); } else if (typeof(IConvertible).IsAssignableFrom(returnType)) { // for regular integers and whatnot - return (T)Convert.ChangeType(value, returnType, CultureInfo.InvariantCulture); + return (TEnum)Convert.ChangeType(value, returnType, CultureInfo.InvariantCulture); } // return as-is from cap. if caller made a mistake then there should be exceptions - return (T)value; + return (TEnum)value; } static ushort GetLowerWord(uint value) diff --git a/NTwain/DataTransferredEventArgs.cs b/NTwain/DataTransferredEventArgs.cs index 0ee159c..e2181a7 100644 --- a/NTwain/DataTransferredEventArgs.cs +++ b/NTwain/DataTransferredEventArgs.cs @@ -12,7 +12,8 @@ namespace NTwain /// Gets pointer to the complete data if the transfer was native. /// The data will be freed once the event handler ends /// so consumers must complete whatever processing before then. - /// For image type this data is DIB (Windows), PICT (old Mac), and TIFF (Linux/OSX). + /// For image type this data is DIB (Windows) or TIFF (Linux). + /// This pointer is already locked for the duration of this event. /// /// The data pointer. public IntPtr NativeData { get; internal set; } @@ -33,6 +34,7 @@ namespace NTwain /// /// The memory data. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public byte[] MemData { get; internal set; } /// diff --git a/NTwain/ITwainOperation.cs b/NTwain/ITwainOperation.cs index f3358bc..651d0ca 100644 --- a/NTwain/ITwainOperation.cs +++ b/NTwain/ITwainOperation.cs @@ -1,9 +1,11 @@ -using NTwain.Triplets; +using NTwain.Data; +using NTwain.Triplets; +using System; namespace NTwain { /// - /// Interface for providing TWAIN triplet operations. + /// Interface for TWAIN triplet operations. /// public interface ITwainOperation { @@ -21,5 +23,52 @@ namespace NTwain /// Gets the triplet operations defined for image data group. /// DGImage DGImage { get; } + + /// + /// Opens the data source manager. This must be the first method used + /// before using other TWAIN functions. Calls to this must be followed by when done with a TWAIN session. + /// + /// + ReturnCode OpenManager(); + + /// + /// Closes the data source manager. + /// + /// + ReturnCode CloseManager(); + + /// + /// Loads the specified source into main memory and causes its initialization. + /// Calls to this must be followed by + /// when not using it anymore. + /// + /// Name of the source. + /// + ReturnCode OpenSource(string sourceProductName); + + /// + /// 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 + /// + /// + ReturnCode CloseSource(); + + /// + /// Enables the source to start transferring. + /// + /// The mode. + /// if set to true any driver UI will display as modal. + /// The window handle if modal. + /// + ReturnCode EnableSource(SourceEnableMode mode, bool modal, IntPtr windowHandle); + + /// + /// Forces the stepping down of an opened source when things gets out of control. + /// Used when session state and source state become out of sync. + /// + /// State of the target. + void ForceStepDown(int targetState); } } diff --git a/NTwain/ITwainSession.cs b/NTwain/ITwainSession.cs index 0819682..0a7b480 100644 --- a/NTwain/ITwainSession.cs +++ b/NTwain/ITwainSession.cs @@ -1,6 +1,7 @@ using NTwain.Data; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; @@ -9,8 +10,20 @@ namespace NTwain /// /// General interface for a TWAIN session. /// - public interface ITwainSession : ITwainState, ITwainOperation + public interface ITwainSession : INotifyPropertyChanged, ITwainOperation { + /// + /// 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; } + /// /// Gets the supported caps for the currently open source. /// diff --git a/NTwain/ITwainState.cs b/NTwain/ITwainState.cs deleted file mode 100644 index 682b06b..0000000 --- a/NTwain/ITwainState.cs +++ /dev/null @@ -1,22 +0,0 @@ -using NTwain.Data; -using System.ComponentModel; -namespace NTwain -{ - /// - /// Interface for keeping track of current TWAIN state with current app and source ids. - /// - public interface ITwainState : INotifyPropertyChanged - { - /// - /// 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; } - } -} diff --git a/NTwain/Internals/WinMemoryManager.cs b/NTwain/Internals/WinMemoryManager.cs index a9576b0..3253b02 100644 --- a/NTwain/Internals/WinMemoryManager.cs +++ b/NTwain/Internals/WinMemoryManager.cs @@ -7,7 +7,6 @@ namespace NTwain { /// /// Provides methods for managing memory on data exchanged with twain sources using old win32 methods. - /// This should only be used after the DSM has been opened. /// class WinMemoryManager : IMemoryManager { diff --git a/NTwain/NTwain.csproj b/NTwain/NTwain.csproj index 48917c9..b65204f 100644 --- a/NTwain/NTwain.csproj +++ b/NTwain/NTwain.csproj @@ -52,7 +52,7 @@ - + @@ -66,7 +66,6 @@ - @@ -130,8 +129,8 @@ - - + + diff --git a/NTwain/Platform.cs b/NTwain/Platform.cs index d1bd2ef..c89e58e 100644 --- a/NTwain/Platform.cs +++ b/NTwain/Platform.cs @@ -11,14 +11,6 @@ namespace NTwain /// public static class Platform { - // Change pinvoke base on where running in 64bit mode. - // Theoretically [DllImport("twaindsm", EntryPoint = "#1")] - // works on both 32 and 64 bit - // but it's not installed on either system by default. - // A proper 64 bit twain driver would've installed it so - // in essence it only exists in 64 bit systems and thus - // the 2 sets of identical pinvokes for windows :( - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")] static Platform() { @@ -69,6 +61,7 @@ namespace NTwain /// /// Gets the for communicating with data sources. + /// This should only be used after the DSM has been opened. /// /// /// The memory manager. diff --git a/NTwain/Data/SourceEnableMode.cs b/NTwain/SourceEnableMode.cs similarity index 94% rename from NTwain/Data/SourceEnableMode.cs rename to NTwain/SourceEnableMode.cs index c497159..00db080 100644 --- a/NTwain/Data/SourceEnableMode.cs +++ b/NTwain/SourceEnableMode.cs @@ -1,4 +1,4 @@ -namespace NTwain.Data +namespace NTwain { /// /// Indicates how the source should be enabled in a TWAIN session. diff --git a/NTwain/TwainException.cs b/NTwain/TwainException.cs index cb12627..64d0f7d 100644 --- a/NTwain/TwainException.cs +++ b/NTwain/TwainException.cs @@ -16,6 +16,16 @@ namespace NTwain /// public TwainException() { } + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public TwainException(string message) + : base(message) + { + + } + /// /// Initializes a new instance of the class. /// @@ -24,6 +34,17 @@ namespace NTwain public TwainException(ReturnCode returnCode, string message) : this(returnCode, message, null) { } + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public TwainException(string message, Exception innerException) + : base(message, innerException) + { + + } + /// /// Initializes a new instance of the class. /// diff --git a/NTwain/TwainSession.cs b/NTwain/TwainSession.cs index 84e4ae7..a7af14d 100644 --- a/NTwain/TwainSession.cs +++ b/NTwain/TwainSession.cs @@ -39,32 +39,6 @@ namespace NTwain TWIdentity _appId; TWUserInterface _twui; - static readonly CapabilityId[] _emptyCapList = new CapabilityId[0]; - - private IList _supportedCaps; - /// - /// Gets the supported caps for the currently open source. - /// - /// - /// The supported caps. - /// - public IList SupportedCaps - { - get - { - if (_supportedCaps == null && State > 3) - { - _supportedCaps = this.GetCapabilities(); - } - return _supportedCaps ?? _emptyCapList; - } - private set - { - _supportedCaps = value; - OnPropertyChanged("SupportedCaps"); - } - } - /// /// Gets or sets the optional synchronization context. /// This allows events to be raised on the thread @@ -129,7 +103,7 @@ namespace NTwain #endregion - #region ITwainState Members + #region ITwainSession Members /// /// Gets the source id used for the session. @@ -149,7 +123,7 @@ namespace NTwain public int State { get { return _state; } - internal protected set + private set { if (value > 0 && value < 8) { @@ -160,6 +134,33 @@ namespace NTwain } } + + static readonly CapabilityId[] _emptyCapList = new CapabilityId[0]; + + private IList _supportedCaps; + /// + /// Gets the supported caps for the currently open source. + /// + /// + /// The supported caps. + /// + public IList SupportedCaps + { + get + { + if (_supportedCaps == null && State > 3) + { + _supportedCaps = this.GetCapabilities(); + } + return _supportedCaps ?? _emptyCapList; + } + private set + { + _supportedCaps = value; + OnPropertyChanged("SupportedCaps"); + } + } + #endregion #region ITwainOperation Members @@ -218,7 +219,8 @@ namespace NTwain /// Name of the property. protected void OnPropertyChanged(string propertyName) { - if (SynchronizationContext == null) + var syncer = SynchronizationContext; + if (syncer == null) { try { @@ -229,7 +231,7 @@ namespace NTwain } else { - SynchronizationContext.Post(o => + syncer.Post(o => { try { @@ -292,6 +294,10 @@ namespace NTwain Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseManager.", Thread.CurrentThread.ManagedThreadId)); rc = DGControl.Parent.CloseDsm(MessageLoop.Instance.LoopHandle); + if (rc == ReturnCode.Success) + { + Platform.MemoryManager = null; + } }); return rc; } @@ -313,8 +319,10 @@ namespace NTwain { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId)); - var source = new TWIdentity(); - source.ProductName = sourceProductName; + var source = new TWIdentity + { + ProductName = sourceProductName + }; rc = DGControl.Identity.OpenDS(source); }); @@ -351,7 +359,6 @@ namespace NTwain /// if set to true any driver UI will display as modal. /// The window handle if modal. /// - /// context public ReturnCode EnableSource(SourceEnableMode mode, bool modal, IntPtr windowHandle) { var rc = ReturnCode.Failure; @@ -398,6 +405,11 @@ namespace NTwain { rc = DGControl.UserInterface.EnableDS(_twui); } + + if (rc != ReturnCode.Success) + { + _callbackObj = null; + } }); return rc; } @@ -501,7 +513,6 @@ namespace NTwain /// Occurs when data has been transferred. /// public event EventHandler DataTransferred; - /// /// Occurs when an error has been encountered during transfer. /// @@ -509,7 +520,8 @@ namespace NTwain /// - /// Raises event and if applicable marshal it asynchronously to the thread. + /// Raises event and if applicable marshal it asynchronously to the thread + /// without exceptions. /// /// The on event function. /// The handler. @@ -540,7 +552,8 @@ namespace NTwain } /// - /// Raises event and if applicable marshal it synchronously to the thread. + /// Raises event and if applicable marshal it synchronously to the thread + /// without exceptions. /// /// The type of the event arguments. /// The on event function. @@ -597,19 +610,19 @@ namespace NTwain /// Called when a data transfer is ready. /// /// The instance containing the event data. - internal protected virtual void OnTransferReady(TransferReadyEventArgs e) { } + protected virtual void OnTransferReady(TransferReadyEventArgs e) { } /// /// Called when data has been transferred. /// /// The instance containing the event data. - internal protected virtual void OnDataTransferred(DataTransferredEventArgs e) { } + protected virtual void OnDataTransferred(DataTransferredEventArgs e) { } /// /// Called when an error has been encountered during transfer. /// /// The instance containing the event data. - internal protected virtual void OnTransferError(TransferErrorEventArgs e) { } + protected virtual void OnTransferError(TransferErrorEventArgs e) { } #endregion @@ -661,7 +674,7 @@ namespace NTwain return ReturnCode.Failure; } - // method that handles msg from the source, whether it's from wndproc or callbacks + // final method that handles msg from the source, whether it's from wndproc or callbacks void HandleSourceMsg(Message msg) { switch (msg) diff --git a/NTwain/TwainSessionExtensions.cs b/NTwain/TwainSessionExtensions.cs index 27e8695..59f03eb 100644 --- a/NTwain/TwainSessionExtensions.cs +++ b/NTwain/TwainSessionExtensions.cs @@ -74,7 +74,7 @@ namespace NTwain /// The session. /// The cap identifier. /// - public static QuerySupport GetCapSupport(this ITwainOperation session, CapabilityId capId) + public static QuerySupport GetCapabilitySupport(this ITwainOperation session, CapabilityId capId) { if (session == null) { throw new ArgumentNullException("session"); } @@ -84,7 +84,7 @@ namespace NTwain var rc = session.DGControl.Capability.QuerySupport(cap); if (rc == ReturnCode.Success) { - var read = CapReadOut.ReadValue(cap); + var read = CapabilityReadOut.ReadValue(cap); if (read.ContainerType == ContainerType.OneValue) { @@ -110,7 +110,7 @@ namespace NTwain var rc = session.DGControl.Capability.GetCurrent(cap); if (rc == ReturnCode.Success) { - var read = CapReadOut.ReadValue(cap); + var read = CapabilityReadOut.ReadValue(cap); switch (read.ContainerType) { @@ -149,7 +149,7 @@ namespace NTwain if (toPopulate == null) { toPopulate = new List(); } - var read = CapReadOut.ReadValue(capability); + var read = CapabilityReadOut.ReadValue(capability); switch (read.ContainerType) { @@ -224,6 +224,8 @@ namespace NTwain /// public static IList CapGetImageXferMech(this ITwainOperation session) { + if (session == null) { throw new ArgumentNullException("session"); } + return session.GetCapabilityValues(CapabilityId.ICapXferMech).CastToEnum(true); } @@ -239,6 +241,8 @@ namespace NTwain /// public static IList CapGetCompression(this ITwainOperation session) { + if (session == null) { throw new ArgumentNullException("session"); } + return session.GetCapabilityValues(CapabilityId.ICapCompression).CastToEnum(true); } @@ -250,6 +254,8 @@ namespace NTwain /// public static ReturnCode CapSetImageCompression(this ITwainOperation session, CompressionType compression) { + if (session == null) { throw new ArgumentNullException("session"); } + using (TWCapability compressCap = new TWCapability(CapabilityId.ICapCompression, new TWOneValue { Item = (uint)compression, ItemType = ItemType.UInt16 })) { return session.DGControl.Capability.Set(compressCap); @@ -500,7 +506,7 @@ namespace NTwain /// Change the auto deskew flag for the current source. /// /// The session. - /// if set to true [use it]. + /// if set to true use it. /// public static ReturnCode CapSetAutoDeskew(this TwainSession session, bool useIt) { @@ -542,7 +548,7 @@ namespace NTwain /// Change the auto rotate flag for the current source. /// /// The session. - /// if set to true [use it]. + /// if set to true use it. /// public static ReturnCode CapSetAutoRotate(this ITwainSession session, bool useIt) { @@ -582,7 +588,7 @@ namespace NTwain /// Change the auto border detection flag for the current source. /// /// The session. - /// if set to true [use it]. + /// if set to true use it. /// public static ReturnCode CapSetBorderDetection(this ITwainSession session, bool useIt) { @@ -632,7 +638,7 @@ namespace NTwain /// Change the duplex flag for the current source. /// /// The session. - /// if set to true [use it]. + /// if set to true to use it. /// public static ReturnCode CapSetDuplex(this ITwainSession session, bool useIt) { @@ -668,7 +674,7 @@ namespace NTwain /// Change the use feeder flag for the current source. /// /// The session. - /// if set to true [use it]. + /// if set to true use it. /// public static ReturnCode CapSetFeeder(this ITwainSession session, bool useIt) { diff --git a/NTwain/TwainStateException.cs b/NTwain/TwainStateException.cs index 36c240a..5f32df6 100644 --- a/NTwain/TwainStateException.cs +++ b/NTwain/TwainStateException.cs @@ -8,6 +8,7 @@ namespace NTwain /// /// Represents an exception from calling a TWAIN triplet operation in the wrong state. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors")] [Serializable] public class TwainStateException : TwainException { diff --git a/README.markdown b/README.md similarity index 100% rename from README.markdown rename to README.md diff --git a/Tests/Tester.WPF/MainWindow.xaml.cs b/Tests/Tester.WPF/MainWindow.xaml.cs index 7f2ca44..a31b3e4 100644 --- a/Tests/Tester.WPF/MainWindow.xaml.cs +++ b/Tests/Tester.WPF/MainWindow.xaml.cs @@ -93,7 +93,7 @@ namespace Tester.WPF var caps = _twainVM.SupportedCaps.Select(o => new CapVM { Cap = o, - Supports = _twainVM.GetCapSupport(o) + Supports = _twainVM.GetCapabilitySupport(o) }).OrderBy(o => o.Name).ToList(); CapList.ItemsSource = caps; } diff --git a/Tests/Tester.WPF/Tester.WPF.csproj b/Tests/Tester.WPF/Tester.WPF.csproj index eb10f7f..b7b2cd3 100644 --- a/Tests/Tester.WPF/Tester.WPF.csproj +++ b/Tests/Tester.WPF/Tester.WPF.csproj @@ -42,7 +42,7 @@ False - ..\..\packages\CommonWin32.2.0.5\lib\net35-Client\CommonWin32.dll + ..\..\packages\CommonWin32.2.0.5.2\lib\net35-Client\CommonWin32.dll ..\..\packages\MvvmLightLibs.4.3.31.1\lib\net40\GalaSoft.MvvmLight.Extras.WPF4.dll @@ -55,7 +55,7 @@ False - ..\..\packages\ModernWPF.1.1.41.3\lib\net40-Client\ModernWPF.dll + ..\..\packages\ModernWPF.1.1.43\lib\net40-Client\ModernWPF.dll diff --git a/Tests/Tester.WPF/packages.config b/Tests/Tester.WPF/packages.config index 8fab5a2..4a2945a 100644 --- a/Tests/Tester.WPF/packages.config +++ b/Tests/Tester.WPF/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/Tests/Tester.Winform/Tester.Winform.csproj b/Tests/Tester.Winform/Tester.Winform.csproj index da25935..1d675d7 100644 --- a/Tests/Tester.Winform/Tester.Winform.csproj +++ b/Tests/Tester.Winform/Tester.Winform.csproj @@ -37,7 +37,7 @@ False - ..\..\packages\CommonWin32.2.0.5\lib\net35-Client\CommonWin32.dll + ..\..\packages\CommonWin32.2.0.5.2\lib\net35-Client\CommonWin32.dll diff --git a/Tests/Tester.Winform/packages.config b/Tests/Tester.Winform/packages.config index a69b1b0..bdeda9a 100644 --- a/Tests/Tester.Winform/packages.config +++ b/Tests/Tester.Winform/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file