Added DG triplet placeholders.

This commit is contained in:
Eugene Wang
2018-11-13 19:30:58 -05:00
parent cad3e5d37f
commit 4d3690874d
17 changed files with 572 additions and 115 deletions

View File

@@ -13,11 +13,22 @@ namespace NetCoreConsole
.Build(); .Build();
using (var session = new TwainSession(config)) using (var session = new TwainSession(config))
{ {
session.PropertyChanged += Session_PropertyChanged;
var handle = IntPtr.Zero;
session.Open(ref handle);
} }
}
Console.WriteLine("Hello World!"); private static void Session_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var session = (TwainSession)sender;
if (e.PropertyName == "State")
{
Console.WriteLine($"State changed to {session.State}");
}
} }
} }
} }

View File

@@ -27,14 +27,6 @@ using TW_UINT8 = System.Byte; // unsigned char
// http://www.mono-project.com/Interop_with_Native_Libraries (old) // http://www.mono-project.com/Interop_with_Native_Libraries (old)
// http://www.mono-project.com/docs/advanced/pinvoke/ (new url) // http://www.mono-project.com/docs/advanced/pinvoke/ (new url)
//////////////////////////////////
// Data structures that
// are passed to the TWAIN method
// are defined as classes to reduce
// ref/out in the low-level calls.
// Others continue to be structs.
//////////////////////////////////
namespace NTwain.Data namespace NTwain.Data
{ {
@@ -241,7 +233,7 @@ namespace NTwain.Data
TW_MEMREF _context; TW_MEMREF _context;
[FieldOffset(520)] // not sure why it should be 520 but whatev [FieldOffset(520)] // not sure why it should be 520 but whatev
Int32 Recursive; Int32 _recursive;
[FieldOffset(520)] [FieldOffset(520)]
TW_BOOL _subdirectories; TW_BOOL _subdirectories;

View File

@@ -1419,8 +1419,8 @@ namespace NTwain.Data
/// </summary> /// </summary>
public bool Recursive public bool Recursive
{ {
get { return _subdirectories == TwainConst.True; } get { return _recursive == 1; }
set { _subdirectories = value ? TwainConst.True : TwainConst.False; } set { _recursive = value ? 1 : 0; }
} }
/// <summary> /// <summary>
@@ -1688,7 +1688,6 @@ namespace NTwain.Data
internal set { _supportedGroups = ((uint)value & 0xffff0000) | (0x0000ffff & _supportedGroups); } internal set { _supportedGroups = ((uint)value & 0xffff0000) | (0x0000ffff & _supportedGroups); }
} }
public string Manufacturer public string Manufacturer
{ {
get { return _manufacturer; } get { return _manufacturer; }

View File

@@ -21,10 +21,6 @@
<Version>4.0.0</Version> <Version>4.0.0</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Folder Include="Triplets\" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Resources\MsgText.Designer.cs"> <Compile Update="Resources\MsgText.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>

View File

@@ -0,0 +1,12 @@
namespace NTwain.Triplets
{
public abstract class BaseTriplet
{
protected TwainSession session;
public BaseTriplet(TwainSession session)
{
this.session = session;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain.Triplets
{
public partial class DGAudio : BaseTriplet
{
internal DGAudio(TwainSession session) : base(session) { }
}
}

View File

@@ -0,0 +1,27 @@
using NTwain.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain.Triplets
{
public partial class Parent : BaseTriplet
{
internal Parent(TwainSession session) : base(session) { }
public ReturnCode OpenDSM(ref IntPtr hWnd)
{
var rc = NativeMethods.DsmWin32(session.Config.AppWin32, null, DataGroups.Control, DataArgumentType.Parent, Message.OpenDSM, ref hWnd);
if (rc == ReturnCode.Success) session.State = TwainState.DsmOpened;
return rc;
}
public ReturnCode CloseDSM(ref IntPtr hWnd)
{
var rc = NativeMethods.DsmWin32(session.Config.AppWin32, null, DataGroups.Control, DataArgumentType.Parent, Message.CloseDSM, ref hWnd);
if (rc == ReturnCode.Success) session.State = TwainState.DsmLoaded;
return rc;
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain.Triplets
{
public partial class DGControl : BaseTriplet
{
internal DGControl(TwainSession session) : base(session) { }
Parent _parent;
internal Parent Parent => _parent ?? (_parent = new Parent(session));
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain.Triplets
{
public partial class DGCustom : BaseTriplet
{
internal DGCustom(TwainSession session) : base(session) { }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain.Triplets
{
public partial class DGImage : BaseTriplet
{
internal DGImage(TwainSession session) : base(session) { }
}
}

View File

@@ -0,0 +1,283 @@
using NTwain.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace NTwain.Triplets
{
static partial class NativeMethods
{
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref IntPtr data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref DataGroups data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_AUDIOINFO data);
//[DllImport(DSM.WinDsmDll, EntryPoint = DSM.EntryName)]
//public static extern ReturnCode DsmWin32(
// [In, Out]TW_IDENTITY origin,
// [In, Out]TW_IDENTITY destination,
// DataGroups dg,
// DataArgumentType dat,
// Message msg,
// ref TWCapability data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_CUSTOMDSDATA data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_DEVICEEVENT data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_CALLBACK data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_CALLBACK2 data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_ENTRYPOINT data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_EVENT data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_FILESYSTEM data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
IntPtr zero,
DataGroups dg,
DataArgumentType dat,
Message msg,
[In, Out]TW_IDENTITY data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_PASSTHRU data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_PENDINGXFERS data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_SETUPFILEXFER data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_SETUPMEMXFER data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_STATUSUTF8 data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_USERINTERFACE data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_CIECOLOR data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_EXTIMAGEINFO data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_FILTER data);
//[DllImport(DSM.WinDsmDll, EntryPoint = DSM.EntryName)]
//public static extern ReturnCode DsmWin32(
// [In, Out]TW_IDENTITY origin,
// [In, Out]TW_IDENTITY destination,
// DataGroups dg,
// DataArgumentType dat,
// Message msg,
// ref TWGrayResponse data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_IMAGEINFO data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_IMAGELAYOUT data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_IMAGEMEMXFER data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_JPEGCOMPRESSION data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_PALETTE8 data);
//[DllImport(DSM.WinDsmDll, EntryPoint = DSM.EntryName)]
//public static extern ReturnCode DsmWin32(
// [In, Out]TW_IDENTITY origin,
// [In, Out]TW_IDENTITY destination,
// DataGroups dg,
// DataArgumentType dat,
// Message msg,
// ref TWRgbResponse data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_STATUS data);
[DllImport(WinDsmDll, EntryPoint = EntryName)]
public static extern ReturnCode DsmWin32(
[In, Out]TW_IDENTITY origin,
[In, Out]TW_IDENTITY destination,
DataGroups dg,
DataArgumentType dat,
Message msg,
ref TW_MEMORY data);
}
}

View File

@@ -0,0 +1,18 @@
using NTwain.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain.Triplets
{
static partial class NativeMethods
{
const string EntryName = "DSM_Entry";
const string WinDsmDll = "twaindsm.dll";
const string LinuxDsmDll = "/usr/local/lib/libtwaindsm.so";
const string MacDsmDll = "/Library/Frameworks/TWAINDSM.framework/TWAINDSM";
}
}

View File

@@ -13,9 +13,11 @@ namespace NTwain
{ {
internal TwainConfig() { } internal TwainConfig() { }
public bool PreferLegacyDsm { get; internal set; } //public bool PreferLegacyDsm { get; internal set; }
public ITW_IDENTITY App { get; internal set; } internal TW_IDENTITY AppWin32 { get; set; }
internal TW_IDENTITY SrcWin32 { get; set; }
internal IMemoryManager MemoryManager { get; set; } internal IMemoryManager MemoryManager { get; set; }
} }

View File

@@ -26,20 +26,20 @@ namespace NTwain
_platform = Environment.OSVersion.Platform; _platform = Environment.OSVersion.Platform;
} }
/// <summary> ///// <summary>
/// Specifies which DSM to use. ///// Specifies which DSM to use.
/// </summary> ///// </summary>
/// <param name="legacyDsm"></param> ///// <param name="legacyDsm"></param>
/// <returns></returns> ///// <returns></returns>
public TwainConfigurationBuilder UseDsm(bool legacyDsm = false) //public TwainConfigurationBuilder UseDsm(bool legacyDsm = false)
{ //{
if (legacyDsm) // if (legacyDsm)
{ // {
if (_64bit) throw new InvalidOperationException("Cannot use legacy DSM under 64bit."); // if (_64bit) throw new InvalidOperationException("Cannot use legacy DSM under 64bit.");
} // }
_legacy = legacyDsm; // _legacy = legacyDsm;
return this; // return this;
} //}
/// <summary> /// <summary>
/// Specifies what kind of data the app can to handle from TWAIN devices. /// Specifies what kind of data the app can to handle from TWAIN devices.
@@ -101,7 +101,7 @@ namespace NTwain
/// <returns></returns> /// <returns></returns>
public TwainConfig Build() public TwainConfig Build()
{ {
ITW_IDENTITY app = null; var config = new TwainConfig();
// todo: change id based on platform // todo: change id based on platform
switch (_platform) switch (_platform)
@@ -110,7 +110,7 @@ namespace NTwain
case PlatformID.Unix: case PlatformID.Unix:
case PlatformID.MacOSX: case PlatformID.MacOSX:
default: default:
app = new TW_IDENTITY config.AppWin32 = new TW_IDENTITY
{ {
DataFunctionalities = DataFunctionalities.App2, DataFunctionalities = DataFunctionalities.App2,
DataGroup = DataGroups.Control | _dg, DataGroup = DataGroups.Control | _dg,
@@ -130,12 +130,7 @@ namespace NTwain
}; };
break; break;
} }
return config;
return new TwainConfig
{
PreferLegacyDsm = _legacy,
App = app
};
} }
} }
} }

View File

@@ -0,0 +1,52 @@
using NTwain.Data;
using NTwain.Triplets;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace NTwain
{
partial class TwainSession : IDisposable
{
private bool disposedValue = false; // To detect redundant calls
/// <summary>
/// Handles actual disposal logic.
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
StepDown(TwainState.DsmLoaded);
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~TwainSession() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
/// <summary>
/// Closes any open TWAIN objects.
/// </summary>
public void Dispose()
{
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
}
}

View File

@@ -0,0 +1,66 @@
using NTwain.Data;
using NTwain.Triplets;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace NTwain
{
partial class TwainSession : INotifyPropertyChanged
{
private TwainState _state;
/// <summary>
/// Gets the logical state of the session.
/// </summary>
public TwainState State
{
get { return _state; }
internal set
{
_state = value;
RaisePropertyChanged(nameof(State));
}
}
DGControl dgControl;
/// <summary>
/// Gets the triplet operations defined for control data group.
/// </summary>
public DGControl DGControl => dgControl ?? (dgControl = new DGControl(this));
DGImage dgImage;
/// <summary>
/// Gets the triplet operations defined for image data group.
/// </summary>
public DGImage DGImage => dgImage ?? (dgImage = new DGImage(this));
DGAudio dgAudio;
/// <summary>
/// Gets the triplet operations defined for audio data group.
/// </summary>
public DGAudio DGAudio => dgAudio ?? (dgAudio = new DGAudio(this));
/// <summary>
/// Gets/sets the direct triplet operation entry for custom values.
/// </summary>
public DGCustom DGCustom { get; set; }
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the <see cref="PropertyChanged"/> event.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
protected void RaisePropertyChanged(string propertyName)
{
var handle = PropertyChanged;
handle?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -1,4 +1,5 @@
using NTwain.Data; using NTwain.Data;
using NTwain.Triplets;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@@ -7,87 +8,36 @@ using System.Text;
namespace NTwain namespace NTwain
{ {
public class TwainSession : INotifyPropertyChanged, IDisposable public partial class TwainSession
{ {
private TwainConfig _config; internal TwainConfig Config;
private IntPtr _hWnd;
public TwainSession(TwainConfig config) public TwainSession(TwainConfig config)
{ {
_config = config; Config = config;
var rc = Open(); }
if (rc != ReturnCode.Success)
public ReturnCode Open(ref IntPtr hWnd)
{
_hWnd = hWnd;
return DGControl.Parent.OpenDSM(ref hWnd);
}
public ReturnCode StepDown(TwainState targetState)
{
var rc = ReturnCode.Failure;
while (State > targetState)
{ {
switch (State)
}
}
private TwainState _state;
/// <summary>
/// Gets the logical state of the session.
/// </summary>
public TwainState State
{
get { return _state; }
internal set
{
_state = value;
RaisePropertyChanged(nameof(State));
}
}
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string property)
{
var handle = PropertyChanged;
handle?.Invoke(this, new PropertyChangedEventArgs(property));
}
ReturnCode Open()
{
if (State < TwainState.DsmOpened)
{
}
throw new NotImplementedException();
}
ReturnCode StepDown(TwainState targetState)
{
throw new NotImplementedException();
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{ {
StepDown(TwainState.DsmLoaded); case TwainState.DsmOpened:
// TODO: dispose managed state (managed objects). rc = DGControl.Parent.CloseDSM(ref _hWnd);
if (rc != ReturnCode.Success) return rc;
break;
} }
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
} }
return rc;
} }
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~TwainSession() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
} }
} }