diff --git a/samples/Sample.WPF/Sample.WPF.csproj b/samples/Sample.WPF/Sample.WPF.csproj index bef1d10..5774039 100644 --- a/samples/Sample.WPF/Sample.WPF.csproj +++ b/samples/Sample.WPF/Sample.WPF.csproj @@ -70,7 +70,7 @@ ..\..\packages\Microsoft.WindowsAPICodePack-Shell.1.1.0.0\lib\Microsoft.WindowsAPICodePack.ShellExtensions.dll - ..\..\packages\ModernWPF.1.3.0\lib\net40-Client\ModernWPF.dll + ..\..\packages\ModernWPF.1.3.4\lib\net40-Client\ModernWPF.dll True diff --git a/samples/Sample.WPF/packages.config b/samples/Sample.WPF/packages.config index b9fb596..aa6d429 100644 --- a/samples/Sample.WPF/packages.config +++ b/samples/Sample.WPF/packages.config @@ -1,10 +1,10 @@  - - - - - - - + + + + + + + \ No newline at end of file diff --git a/src/NTwain/CapWrapper.cs b/src/NTwain/CapWrapper.cs index 2bccf57..eebd6db 100644 --- a/src/NTwain/CapWrapper.cs +++ b/src/NTwain/CapWrapper.cs @@ -300,13 +300,43 @@ namespace NTwain return default(TValue); } + /// + /// Gets all the possible values of this capability without expanding. + /// This may be required to work with large range values that cannot be safely enumerated + /// with . + /// + /// + public CapabilityReader GetValuesRaw() + { + using (TWCapability cap = new TWCapability(Capability)) + { + var rc = _source.DGControl.Capability.Get(cap); + if (rc == ReturnCode.Success) + { + return CapabilityReader.ReadValue(cap); + } + } + return null; + } + + /// + /// Converts the object values into typed values using the conversion routine + /// for this capability. + /// + /// The values. + /// + public IEnumerable ConvertValues(IEnumerable values) + { + return values.Select(o => _getConvertRoutine(o)); + } + /// /// Gets all the possible values of this capability. /// /// - public IList GetValues() + public IEnumerable GetValues() { - return _source.Capabilities.GetValues(Capability).Select(o => _getConvertRoutine(o)).ToList(); + return _source.Capabilities.GetValues(Capability).Select(o => _getConvertRoutine(o));//.ToList(); } /// @@ -366,7 +396,7 @@ namespace NTwain /// [Experimental] Gets the display names for possible values of this capability. /// /// - public IList GetLabelEnum() + public IEnumerable GetLabelEnum() { var list = new List(); @@ -375,10 +405,10 @@ namespace NTwain var rc = _source.DGControl.Capability.GetLabelEnum(cap); if (rc == ReturnCode.Success) { - CapabilityReader.ReadValue(cap).PopulateFromCapValues(list); + return CapabilityReader.ReadValue(cap).EnumerateCapValues().Select(o => o.ToString()); } } - return list.Select(o => o.ToString()).ToList(); + return Enumerable.Empty(); } #endregion diff --git a/src/NTwain/Capabilities.cs b/src/NTwain/Capabilities.cs index 30dea0d..b117543 100644 --- a/src/NTwain/Capabilities.cs +++ b/src/NTwain/Capabilities.cs @@ -134,18 +134,17 @@ namespace NTwain /// /// The capability id. /// - public IList GetValues(CapabilityId capabilityId) + public IEnumerable GetValues(CapabilityId capabilityId) { - var list = new List(); using (TWCapability cap = new TWCapability(capabilityId)) { var rc = _source.DGControl.Capability.Get(cap); if (rc == ReturnCode.Success) { - CapabilityReader.ReadValue(cap).PopulateFromCapValues(list); + return CapabilityReader.ReadValue(cap).EnumerateCapValues(); } } - return list; + return Enumerable.Empty(); } /// diff --git a/src/NTwain/CapabilityReader.cs b/src/NTwain/CapabilityReader.cs index 45ce2ed..988aae2 100644 --- a/src/NTwain/CapabilityReader.cs +++ b/src/NTwain/CapabilityReader.cs @@ -2,7 +2,9 @@ using NTwain.Properties; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; +using System.Linq; using System.Runtime.InteropServices; namespace NTwain @@ -75,7 +77,7 @@ namespace NTwain ContainerType = capability.ContainerType, }.ReadRangeValue(baseAddr); default: - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, + throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.CapHasBadContainer, capability.Capability, capability.ContainerType), "capability"); } } @@ -94,6 +96,14 @@ namespace NTwain } } + /// + /// Initializes a new instance of the class. + /// + public CapabilityReader() + { + RangeCount = -1; + } + #region common prop /// @@ -121,7 +131,7 @@ namespace NTwain public object OneValue { get; private set; } /// - /// Gets the collection values if container is or . + /// Gets the collection values if container is or . /// /// /// The collection values. @@ -182,45 +192,52 @@ namespace NTwain /// public object RangeStepSize { get; private set; } + /// + /// Gets the number of range values if range is expanded. + /// You should check for this before expanding range type containers to prevent + /// possible . + /// + /// + /// The range count. + /// + public int RangeCount { get; private set; } + #endregion #region reader methods /// - /// Don't care what contain it is, just populates the specified list with the capability values (count be one or many). + /// Don't care what container it is, just enumerate the capability values. /// - /// The list to populate the values. /// - public IList PopulateFromCapValues(IList toPopulate) + public IEnumerable EnumerateCapValues() { - if (toPopulate == null) { toPopulate = new List(); } - switch (ContainerType) { case ContainerType.OneValue: - if (OneValue != null) - { - toPopulate.Add(OneValue); - } - break; + return EnumerateOneValue(); case ContainerType.Array: case ContainerType.Enum: if (CollectionValues != null) { - foreach (var o in CollectionValues) - { - toPopulate.Add(o); - } + return CollectionValues; } break; case ContainerType.Range: - PopulateRange(toPopulate); - break; + return EnumerateRange(); } - return toPopulate; + return Enumerable.Empty(); } - private void PopulateRange(IList toPopulate) + IEnumerable EnumerateOneValue() + { + if (OneValue != null) + { + yield return OneValue; + } + } + + IEnumerable EnumerateRange() { // horrible cast but should work. // in the for loop we also compare against min in case the step @@ -235,7 +252,7 @@ namespace NTwain for (var i = min; i >= min && i <= max; i += step) { - toPopulate.Add(i); + yield return i; } } break; @@ -247,7 +264,7 @@ namespace NTwain for (var i = min; i >= min && i <= max; i += step) { - toPopulate.Add(i); + yield return i; } } break; @@ -259,7 +276,7 @@ namespace NTwain for (var i = min; i >= min && i <= max; i += step) { - toPopulate.Add(i); + yield return i; } } break; @@ -272,7 +289,7 @@ namespace NTwain for (var i = min; i >= min && i <= max; i += step) { - toPopulate.Add(i); + yield return i; } } break; @@ -284,7 +301,7 @@ namespace NTwain for (var i = min; i >= min && i <= max; i += step) { - toPopulate.Add(i); + yield return i; } } break; @@ -296,7 +313,7 @@ namespace NTwain for (var i = min; i >= min && i <= max; i += step) { - toPopulate.Add(i); + yield return i; } } break; @@ -308,13 +325,27 @@ namespace NTwain for (var i = min; i >= min && i <= max; i += step) { - toPopulate.Add(i); + yield return i; } } break; } } + ///// + ///// Don't care what container it is, just populate the specified list with the capability values (count be one or many). + ///// + ///// The list to populate the values. + ///// + //public IList PopulateFromCapValues(IList toPopulate) + //{ + // if (toPopulate == null) { toPopulate = new List(); } + // foreach(var obj in EnumerateCapValues()) + // { + // toPopulate.Add(obj); + // } + // return toPopulate; + //} CapabilityReader ReadOneValue(IntPtr baseAddr) { @@ -377,16 +408,75 @@ namespace NTwain RangeDefaultValue = baseAddr.ReadValue(ref offset, ItemType); RangeCurrentValue = baseAddr.ReadValue(ref offset, ItemType); - //RangeMinValue = (uint)Marshal.ReadInt32(baseAddr, offset); - //offset += 4; - //RangeMaxValue = (uint)Marshal.ReadInt32(baseAddr, offset); - //offset += 4; - //RangeStepSize = (uint)Marshal.ReadInt32(baseAddr, offset); - //offset += 4; - //RangeDefaultValue = (uint)Marshal.ReadInt32(baseAddr, offset); - //offset += 4; - //RangeCurrentValue = (uint)Marshal.ReadInt32(baseAddr, offset); + // do range count + switch (ItemType) + { + case Data.ItemType.Fix32: + { + var min = (TWFix32)RangeMinValue; + var max = (TWFix32)RangeMaxValue; + var step = (TWFix32)RangeStepSize; + + RangeCount = (int)((max - min) / step) + 1; + } + break; + case Data.ItemType.UInt32: + { + var min = (uint)RangeMinValue; + var max = (uint)RangeMaxValue; + var step = (uint)RangeStepSize; + + RangeCount = (int)((max - min) / step) + 1; + } + break; + case Data.ItemType.Int32: + { + var min = (int)RangeMinValue; + var max = (int)RangeMaxValue; + var step = (int)RangeStepSize; + + RangeCount = ((max - min) / step) + 1; + } + break; + // these should never happen since TW_ENUM fields are 4 bytes but you never know + case Data.ItemType.UInt16: + { + var min = (ushort)RangeMinValue; + var max = (ushort)RangeMaxValue; + var step = (ushort)RangeStepSize; + + RangeCount = ((max - min) / step) + 1; + } + break; + case Data.ItemType.Int16: + { + var min = (short)RangeMinValue; + var max = (short)RangeMaxValue; + var step = (short)RangeStepSize; + + RangeCount = ((max - min) / step) + 1; + } + break; + case Data.ItemType.UInt8: + { + var min = (byte)RangeMinValue; + var max = (byte)RangeMaxValue; + var step = (byte)RangeStepSize; + + RangeCount = ((max - min) / step) + 1; + } + break; + case Data.ItemType.Int8: + { + var min = (sbyte)RangeMinValue; + var max = (sbyte)RangeMaxValue; + var step = (sbyte)RangeStepSize; + + RangeCount = ((max - min) / step) + 1; + } + break; + } return this; } diff --git a/src/NTwain/ICapWrapper.cs b/src/NTwain/ICapWrapper.cs index 5164b9c..d6bd1dc 100644 --- a/src/NTwain/ICapWrapper.cs +++ b/src/NTwain/ICapWrapper.cs @@ -91,11 +91,27 @@ namespace NTwain /// CapabilityId Capability { get; } + /// + /// Gets all the possible values of this capability without expanding. + /// This may be required to work with large range values that cannot be safely enumerated + /// with . + /// + /// + CapabilityReader GetValuesRaw(); + + /// + /// Converts the object values into typed values using the conversion routine + /// for this capability. + /// + /// The values. + /// + IEnumerable ConvertValues(IEnumerable values); + /// /// Gets all the possible values of this capability. /// /// - IList GetValues(); + IEnumerable GetValues(); /// /// Gets the current value of this capability. @@ -125,7 +141,7 @@ namespace NTwain /// [Experimental] Gets the display names for possible values of this capability. /// /// - IList GetLabelEnum(); + IEnumerable GetLabelEnum(); /// /// Gets a value indicating whether this capability is at all supported. @@ -162,11 +178,11 @@ namespace NTwain /// The value. /// ReturnCode SetValue(TValue value);/// - /// - /// A version of Set that uses an array. - /// - /// The value. - /// + /// + /// A version of Set that uses an array. + /// + /// The value. + /// ReturnCode SetValue(TWArray value); /// diff --git a/src/NTwain/Properties/VersionInfo.cs b/src/NTwain/Properties/VersionInfo.cs index 90a0550..3e1a861 100644 --- a/src/NTwain/Properties/VersionInfo.cs +++ b/src/NTwain/Properties/VersionInfo.cs @@ -23,7 +23,7 @@ namespace NTwain /// /// The build release version number. /// - public const string Build = "3.3.5"; // change this for each nuget release + public const string Build = "3.3.6"; // change this for each nuget release }