using NTwain.Data; using NTwain.Internals; using NTwain.Triplets; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text; using System.Threading; namespace NTwain { /// /// Represents a TWAIN data source. /// public partial class TwainSource : INotifyPropertyChanged { ITwainSessionInternal _session; internal TwainSource(ITwainSessionInternal session, TWIdentity sourceId) { _session = session; Identity = sourceId; } /// /// Opens the source for capability negotiation. /// /// public ReturnCode Open() { var rc = ReturnCode.Failure; MessageLoop.Instance.Invoke(() => { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId)); rc = _session.DGControl.Identity.OpenDS(this); }); return rc; } /// /// Closes the source. /// /// public ReturnCode Close() { var rc = ReturnCode.Failure; MessageLoop.Instance.Invoke(() => { Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId)); rc = _session.DGControl.Identity.CloseDS(); if (rc == ReturnCode.Success) { SupportedCaps = null; } }); return rc; } /// /// Enables the source to start transferring. /// /// The mode. /// if set to true any driver UI will display as modal. /// The window handle if modal. /// public ReturnCode StartTransfer(SourceEnableMode mode, bool modal, IntPtr windowHandle) { return _session.EnableSource(mode, modal, windowHandle); } /// /// Gets the source status. Only call this at state 4 or higher. /// /// public TWStatus GetStatus() { TWStatus stat; _session.DGControl.Status.GetSource(out stat); return stat; } /// /// Gets the source status. Only call this at state 4 or higher. /// /// public TWStatusUtf8 GetStatusUtf8() { TWStatusUtf8 stat; _session.DGControl.StatusUtf8.GetSource(out stat); return stat; } #region properties internal TWIdentity Identity { get; private set; } /// /// Gets the source's product name. /// /// /// The name. /// public string Name { get { return Identity.ProductName; } } /// /// Gets the source's manufacturer name. /// /// /// The manufacturer. /// public string Manufacturer { get { return Identity.Manufacturer; } } /// /// Gets the source's product family. /// /// /// The product family. /// public string ProductFamily { get { return Identity.ProductFamily; } } /// /// Gets the version information. /// /// /// The version. /// public TWVersion Version { get { return Identity.Version; } } /// /// Gets the supported data group. /// /// /// The data group. /// public DataGroups DataGroup { get { return Identity.DataGroup; } } /// /// Gets the supported TWAIN protocol major number. /// /// /// The protocol major number. /// public int ProtocolMajor { get { return Identity.ProtocolMajor; } } /// /// Gets the supported TWAIN protocol minor number. /// /// /// The protocol minor number. /// public int ProtocolMinor { get { return Identity.ProtocolMinor; } } static readonly CapabilityId[] _emptyCapList = new CapabilityId[0]; private IList _supportedCaps; /// /// Gets the supported caps for this source. /// /// /// The supported caps. /// public IList SupportedCaps { get { if (_supportedCaps == null && _session.State > 3) { _supportedCaps = CapGetValues(CapabilityId.CapSupportedCaps).CastToEnum(false); } return _supportedCaps ?? _emptyCapList; } private set { _supportedCaps = value; OnPropertyChanged("SupportedCaps"); } } /// /// Gets the triplet operations defined for control data group. /// public DGControl DGControl { get { return _session.DGControl; } } /// /// Gets the triplet operations defined for image data group. /// public DGImage DGImage { get { return _session.DGImage; } } /// /// Gets the direct triplet operation entry for custom values. /// public DGCustom DGCustom { get { return _session.DGCustom; } } #endregion #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 } }