diff --git a/NTwain/Data/TwainValues.cs b/NTwain/Data/TwainValues.cs index 6fa7c37..11d599d 100644 --- a/NTwain/Data/TwainValues.cs +++ b/NTwain/Data/TwainValues.cs @@ -2056,7 +2056,20 @@ namespace NTwain.Data Constrainable = 0x40, GetHelp = 0x100, GetLabel = 0x200, - GetLabelEnum = 0x400 + GetLabelEnum = 0x400, + + /// + /// Cap applies to entire session/machine. + /// + Machine = 0x1000, + /// + /// Cap applies to bitonal cameras. + /// + Bitonal = 0x2000, + /// + /// Cap applies to color cameras. + /// + Color = 0x4000 } /// diff --git a/NTwain/Internals/TransferLogic.cs b/NTwain/Internals/TransferLogic.cs index 8bb93a4..acff1bb 100644 --- a/NTwain/Internals/TransferLogic.cs +++ b/NTwain/Internals/TransferLogic.cs @@ -70,7 +70,15 @@ namespace NTwain.Internals if (xferGroup == DataGroups.None || (xferGroup & DataGroups.Image) == DataGroups.Image) { - var mech = session.CurrentSource.CapGetCurrent(CapabilityId.ICapXferMech).ConvertToEnum(); + // default to memory + var mech = XferMech.Memory; + + object mechRaw = session.CurrentSource.CapGetCurrent(CapabilityId.ICapXferMech); + if (mechRaw != null) + { + mech = mechRaw.ConvertToEnum(); + } + switch (mech) { case XferMech.Memory: @@ -110,9 +118,13 @@ namespace NTwain.Internals } while (rc == ReturnCode.Success && pending.Count != 0); - session.ChangeState(5, true); - session.DisableSource(); - + // 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) + { + session.ChangeState(5, true); + session.DisableSource(); + } } #region audio xfers diff --git a/NTwain/Properties/VersionInfo.cs b/NTwain/Properties/VersionInfo.cs index 183c8b0..2f2ce7b 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.1"; + public const string Build = "2.0.3"; } } \ No newline at end of file diff --git a/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs b/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs index f1e8a37..5cec36a 100644 --- a/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs +++ b/NTwain/Triplets/DGImage/DGImage.ImageMemFileXfer.cs @@ -15,7 +15,7 @@ namespace NTwain.Triplets /// public ReturnCode Get(TWImageMemXfer xfer) { - Session.VerifyState(6, 6, DataGroups.Image, DataArgumentType.ImageMemFileXfer, Message.Get); + Session.VerifyState(6, 7, DataGroups.Image, DataArgumentType.ImageMemFileXfer, Message.Get); return Dsm.DsmEntry(Session.AppId, Session.CurrentSource.Identity, Message.Get, xfer); } diff --git a/NTwain/TwainSource.cs b/NTwain/TwainSource.cs index 54114a3..b9b2736 100644 --- a/NTwain/TwainSource.cs +++ b/NTwain/TwainSource.cs @@ -15,7 +15,7 @@ namespace NTwain /// /// Represents a TWAIN data source. /// - public partial class TwainSource : INotifyPropertyChanged + public partial class TwainSource { ITwainSessionInternal _session; @@ -179,7 +179,7 @@ namespace NTwain private set { _supportedCaps = value; - OnPropertyChanged("SupportedCaps"); + //OnPropertyChanged("SupportedCaps"); } } @@ -219,41 +219,82 @@ namespace NTwain #endregion - #region INotifyPropertyChanged Members + //#region INotifyPropertyChanged Members + + ///// + ///// Occurs when a property value changes. + ///// + //public event PropertyChangedEventHandler PropertyChanged; + + ///// + ///// Raises the event. + ///// + ///// Name of the property. + //protected void OnPropertyChanged(string propertyName) + //{ + // var syncer = _session.SynchronizationContext; + // if (syncer == null) + // { + // try + // { + // var hand = PropertyChanged; + // if (hand != null) { hand(this, new PropertyChangedEventArgs(propertyName)); } + // } + // catch { } + // } + // else + // { + // syncer.Post(o => + // { + // try + // { + // var hand = PropertyChanged; + // if (hand != null) { hand(this, new PropertyChangedEventArgs(propertyName)); } + // } + // catch { } + // }, null); + // } + //} + + //#endregion + + #region cameras /// - /// Occurs when a property value changes. + /// Gets the cameras supported by the source. /// - public event PropertyChangedEventHandler PropertyChanged; - - /// - /// Raises the event. - /// - /// Name of the property. - protected void OnPropertyChanged(string propertyName) + /// + public IList GetCameras() { - var syncer = _session.SynchronizationContext; - if (syncer == null) + TWFileSystem fs = new TWFileSystem(); + List cams = new List(); + var rc = DGControl.FileSystem.GetFirstFile(fs); + while (rc == ReturnCode.Success) { - try + switch (fs.FileType) { - var hand = PropertyChanged; - if (hand != null) { hand(this, new PropertyChangedEventArgs(propertyName)); } + case FileType.Camera: + case FileType.CameraBottom: + case FileType.CameraTop: + case FileType.CameraPreview: + cams.Add(fs.OutputName); + break; } - catch { } - } - else - { - syncer.Post(o => - { - try - { - var hand = PropertyChanged; - if (hand != null) { hand(this, new PropertyChangedEventArgs(propertyName)); } - } - catch { } - }, null); + rc = DGControl.FileSystem.GetNextFile(fs); } + return cams; + } + + /// + /// Sets the target camera for cap negotiation that can be set per camera. + /// + /// + /// + public ReturnCode SetCamera(string cameraName) + { + TWFileSystem fs = new TWFileSystem(); + fs.InputName = cameraName; + return DGControl.FileSystem.ChangeDirectory(fs); } #endregion diff --git a/Tests/Tester.Winform/TestForm.cs b/Tests/Tester.Winform/TestForm.cs index 74050bb..bebe5f1 100644 --- a/Tests/Tester.Winform/TestForm.cs +++ b/Tests/Tester.Winform/TestForm.cs @@ -105,19 +105,22 @@ namespace Tester.Winform private void CleanupTwain() { - if (_twain.State == 4) + if (_twain != null) { - _twain.CurrentSource.Close(); - } - if (_twain.State == 3) - { - _twain.Close(); - } + if (_twain.State == 4) + { + _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); + } } }