mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
Merged wrapper-idea into master
This commit is contained in:
commit
f69698f90a
@ -37,26 +37,6 @@ namespace NTwain
|
||||
/// <value>The state.</value>
|
||||
int State { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for audio data group.
|
||||
/// </summary>
|
||||
DGAudio DGAudio { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for control data group.
|
||||
/// </summary>
|
||||
DGControl DGControl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for image data group.
|
||||
/// </summary>
|
||||
DGImage DGImage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the direct triplet operation entry for custom values.
|
||||
/// </summary>
|
||||
DGCustom DGCustom { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Try to show the built-in source selector dialog and return the selected source.
|
||||
/// This is not recommended and is only included for completeness.
|
||||
|
@ -1,4 +1,5 @@
|
||||
using NTwain.Data;
|
||||
using NTwain.Triplets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
@ -46,5 +47,25 @@ namespace NTwain.Internals
|
||||
|
||||
ReturnCode EnableSource(SourceEnableMode mode, bool modal, IntPtr windowHandle);
|
||||
SynchronizationContext SynchronizationContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for audio data group.
|
||||
/// </summary>
|
||||
DGAudio DGAudio { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for control data group.
|
||||
/// </summary>
|
||||
DGControl DGControl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for image data group.
|
||||
/// </summary>
|
||||
DGImage DGImage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the direct triplet operation entry for custom values.
|
||||
/// </summary>
|
||||
DGCustom DGCustom { get; }
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ namespace NTwain.Triplets
|
||||
/// <summary>
|
||||
/// Represents <see cref="DataGroups.Audio"/>.
|
||||
/// </summary>
|
||||
public sealed class DGAudio
|
||||
sealed class DGAudio
|
||||
{
|
||||
ITwainSessionInternal _session;
|
||||
internal DGAudio(ITwainSessionInternal session)
|
||||
|
@ -62,7 +62,7 @@ namespace NTwain
|
||||
return __ownedSources[key] = new TwainSource(session, sourceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the optional synchronization context.
|
||||
@ -151,7 +151,7 @@ namespace NTwain
|
||||
get
|
||||
{
|
||||
TWIdentity id;
|
||||
if (DGControl.Identity.GetDefault(out id) == ReturnCode.Success)
|
||||
if (((ITwainSessionInternal)this).DGControl.Identity.GetDefault(out id) == ReturnCode.Success)
|
||||
{
|
||||
return GetSourceInstance(this, id);
|
||||
}
|
||||
@ -161,7 +161,7 @@ namespace NTwain
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
DGControl.Identity.Set(value.Identity);
|
||||
((ITwainSessionInternal)this).DGControl.Identity.Set(value.Identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,7 +174,7 @@ namespace NTwain
|
||||
public TwainSource ShowSourceSelector()
|
||||
{
|
||||
TWIdentity id;
|
||||
if (DGControl.Identity.UserSelect(out id) == ReturnCode.Success)
|
||||
if (((ITwainSessionInternal)this).DGControl.Identity.UserSelect(out id) == ReturnCode.Success)
|
||||
{
|
||||
return GetSourceInstance(this, id);
|
||||
}
|
||||
@ -210,7 +210,7 @@ namespace NTwain
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for audio data group.
|
||||
/// </summary>
|
||||
public DGAudio DGAudio
|
||||
DGAudio ITwainSessionInternal.DGAudio
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -220,10 +220,7 @@ namespace NTwain
|
||||
}
|
||||
|
||||
DGControl _dgControl;
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for control data group.
|
||||
/// </summary>
|
||||
public DGControl DGControl
|
||||
DGControl ITwainSessionInternal.DGControl
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -233,10 +230,7 @@ namespace NTwain
|
||||
}
|
||||
|
||||
DGImage _dgImage;
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for image data group.
|
||||
/// </summary>
|
||||
public DGImage DGImage
|
||||
DGImage ITwainSessionInternal.DGImage
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -246,10 +240,7 @@ namespace NTwain
|
||||
}
|
||||
|
||||
DGCustom _dgCustom;
|
||||
/// <summary>
|
||||
/// Gets the direct triplet operation entry for custom values.
|
||||
/// </summary>
|
||||
public DGCustom DGCustom
|
||||
DGCustom ITwainSessionInternal.DGCustom
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -257,6 +248,7 @@ namespace NTwain
|
||||
return _dgCustom;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the data source manager. This must be the first method used
|
||||
/// before using other TWAIN functions. Calls to this must be followed by <see cref="Close"/> when done with a TWAIN session.
|
||||
@ -269,14 +261,14 @@ namespace NTwain
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenManager.", Thread.CurrentThread.ManagedThreadId));
|
||||
|
||||
rc = DGControl.Parent.OpenDsm(MessageLoop.Instance.LoopHandle);
|
||||
rc = ((ITwainSessionInternal)this).DGControl.Parent.OpenDsm(MessageLoop.Instance.LoopHandle);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
// if twain2 then get memory management functions
|
||||
if ((_appId.DataFunctionalities & DataFunctionalities.Dsm2) == DataFunctionalities.Dsm2)
|
||||
{
|
||||
TWEntryPoint entry;
|
||||
rc = DGControl.EntryPoint.Get(out entry);
|
||||
rc = ((ITwainSessionInternal)this).DGControl.EntryPoint.Get(out entry);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
Platform.MemoryManager = entry;
|
||||
@ -303,7 +295,7 @@ namespace NTwain
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseManager.", Thread.CurrentThread.ManagedThreadId));
|
||||
|
||||
rc = DGControl.Parent.CloseDsm(MessageLoop.Instance.LoopHandle);
|
||||
rc = ((ITwainSessionInternal)this).DGControl.Parent.CloseDsm(MessageLoop.Instance.LoopHandle);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
Platform.MemoryManager = null;
|
||||
@ -321,13 +313,14 @@ namespace NTwain
|
||||
public IEnumerable<TwainSource> GetSources()
|
||||
{
|
||||
TWIdentity srcId;
|
||||
var rc = DGControl.Identity.GetFirst(out srcId);
|
||||
var rc = ((ITwainSessionInternal)this).DGControl.Identity.GetFirst(out srcId);
|
||||
while (rc == ReturnCode.Success)
|
||||
{
|
||||
yield return GetSourceInstance(this, srcId);
|
||||
rc = DGControl.Identity.GetNext(out srcId);
|
||||
rc = ((ITwainSessionInternal)this).DGControl.Identity.GetNext(out srcId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the manager status. Only call this at state 2 or higher.
|
||||
/// </summary>
|
||||
@ -335,7 +328,7 @@ namespace NTwain
|
||||
public TWStatus GetStatus()
|
||||
{
|
||||
TWStatus stat;
|
||||
DGControl.Status.GetManager(out stat);
|
||||
((ITwainSessionInternal)this).DGControl.Status.GetManager(out stat);
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -346,7 +339,7 @@ namespace NTwain
|
||||
public TWStatusUtf8 GetStatusUtf8()
|
||||
{
|
||||
TWStatusUtf8 stat;
|
||||
DGControl.StatusUtf8.GetManager(out stat);
|
||||
((ITwainSessionInternal)this).DGControl.StatusUtf8.GetManager(out stat);
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -414,7 +407,7 @@ namespace NTwain
|
||||
if (_appId.ProtocolMajor >= 2 && _appId.ProtocolMinor >= 2)
|
||||
{
|
||||
var cb = new TWCallback2(HandleCallback);
|
||||
var rc2 = DGControl.Callback2.RegisterCallback(cb);
|
||||
var rc2 = ((ITwainSessionInternal)this).DGControl.Callback2.RegisterCallback(cb);
|
||||
|
||||
if (rc2 == ReturnCode.Success)
|
||||
{
|
||||
@ -426,7 +419,7 @@ namespace NTwain
|
||||
{
|
||||
var cb = new TWCallback(HandleCallback);
|
||||
|
||||
var rc2 = DGControl.Callback.RegisterCallback(cb);
|
||||
var rc2 = ((ITwainSessionInternal)this).DGControl.Callback.RegisterCallback(cb);
|
||||
|
||||
if (rc2 == ReturnCode.Success)
|
||||
{
|
||||
@ -442,11 +435,11 @@ namespace NTwain
|
||||
|
||||
if (mode == SourceEnableMode.ShowUIOnly)
|
||||
{
|
||||
rc = DGControl.UserInterface.EnableDSUIOnly(_twui);
|
||||
rc = ((ITwainSessionInternal)this).DGControl.UserInterface.EnableDSUIOnly(_twui);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = DGControl.UserInterface.EnableDS(_twui);
|
||||
rc = ((ITwainSessionInternal)this).DGControl.UserInterface.EnableDS(_twui);
|
||||
}
|
||||
|
||||
if (rc != ReturnCode.Success)
|
||||
@ -465,7 +458,7 @@ namespace NTwain
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: DisableSource.", Thread.CurrentThread.ManagedThreadId));
|
||||
|
||||
rc = DGControl.UserInterface.DisableDS(_twui);
|
||||
rc = ((ITwainSessionInternal)this).DGControl.UserInterface.DisableDS(_twui);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
_callbackObj = null;
|
||||
@ -506,11 +499,11 @@ namespace NTwain
|
||||
{
|
||||
if (targetState < 7)
|
||||
{
|
||||
DGControl.PendingXfers.EndXfer(new TWPendingXfers());
|
||||
((ITwainSessionInternal)this).DGControl.PendingXfers.EndXfer(new TWPendingXfers());
|
||||
}
|
||||
if (targetState < 6)
|
||||
{
|
||||
DGControl.PendingXfers.Reset(new TWPendingXfers());
|
||||
((ITwainSessionInternal)this).DGControl.PendingXfers.Reset(new TWPendingXfers());
|
||||
}
|
||||
if (targetState < 5)
|
||||
{
|
||||
@ -690,7 +683,7 @@ namespace NTwain
|
||||
|
||||
var evt = new TWEvent();
|
||||
evt.pEvent = msgPtr;
|
||||
if (handled = (DGControl.Event.ProcessEvent(evt) == ReturnCode.DSEvent))
|
||||
if (handled = (((ITwainSessionInternal)this).DGControl.Event.ProcessEvent(evt) == ReturnCode.DSEvent))
|
||||
{
|
||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: HandleWndProcMessage at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, evt.TWMessage));
|
||||
|
||||
@ -735,7 +728,7 @@ namespace NTwain
|
||||
break;
|
||||
case Message.DeviceEvent:
|
||||
TWDeviceEvent de;
|
||||
var rc = DGControl.DeviceEvent.Get(out de);
|
||||
var rc = ((ITwainSessionInternal)this).DGControl.DeviceEvent.Get(out de);
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
SafeSyncableRaiseOnEvent(OnDeviceEvent, DeviceEvent, new DeviceEventArgs(de));
|
||||
|
@ -1,5 +1,6 @@
|
||||
using NTwain.Data;
|
||||
using NTwain.Internals;
|
||||
using NTwain.Triplets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@ -182,6 +183,40 @@ namespace NTwain
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for control data group.
|
||||
/// </summary>
|
||||
public DGControl DGControl
|
||||
{
|
||||
get
|
||||
{
|
||||
return _session.DGControl;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the triplet operations defined for image data group.
|
||||
/// </summary>
|
||||
public DGImage DGImage
|
||||
{
|
||||
get
|
||||
{
|
||||
return _session.DGImage;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the direct triplet operation entry for custom values.
|
||||
/// </summary>
|
||||
public DGCustom DGCustom
|
||||
{
|
||||
get
|
||||
{
|
||||
return _session.DGCustom;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region INotifyPropertyChanged Members
|
||||
|
79
README.md
79
README.md
@ -19,10 +19,9 @@ To properly use this lib you will need to be reasonably familiar with the TWAIN
|
||||
and how it works in general (especially capability).
|
||||
The spec can be downloaded from [twain.org](http://twain.org/).
|
||||
|
||||
Except for certain "important" state-changing calls that have been
|
||||
abstract away, most triplet operations are
|
||||
Except for those that have been abstracted away with .net equivalents, most triplet operations are
|
||||
provided as-is so you will need to know when and how to use them.
|
||||
There are no high-level, single-line scan-a-page-for-me-now functions.
|
||||
There are no high-level, single-line scan-a-page-for-me-now functions yet.
|
||||
|
||||
The main class to use is TwainSession. You can either use it directly by subscribing
|
||||
to the important events or sub-class it and override the OnMethods related to those events.
|
||||
@ -40,6 +39,9 @@ var session = new TwainSession(appId);
|
||||
session.TransferReady += ...
|
||||
session.DataTransferred += ...
|
||||
|
||||
// finally open it
|
||||
session.Open();
|
||||
|
||||
```
|
||||
|
||||
TwainSession class provides many events, but these 2 are the most important
|
||||
@ -50,23 +52,44 @@ or all subsequent transfers using the event object.
|
||||
what you've specified using the TWAIN API before starting the transfer.
|
||||
|
||||
|
||||
To get into transfer mode, you'll have to call these methods after setting up the session:
|
||||
|
||||
1. OpenManager() - opens the TWAIN data source manager (DSM). You can really keep this open throughout the app life time with no ill effect.
|
||||
2. OpenSource() - opens a target device. You can continue to open and close sources as long as DSM is open.
|
||||
3. EnableSource() - starts transferring
|
||||
|
||||
After transfer has completed (you are notified of this with the SourceDisabled event)
|
||||
and you're done with TWAIN, you can call their equivalents in correct hierarchical order like html
|
||||
|
||||
1. CloseSource()
|
||||
2. CloseManager()
|
||||
Once you've setup and opened the session, you can get available sources, pick one to use,
|
||||
and call Open() to start using it.
|
||||
|
||||
|
||||
While most TWAIN APIs are done via the low-level triplet calls, this lib does provide some
|
||||
commonly used functions as extension methods to TwainSession (especially capability functions).
|
||||
This should make setting simple things such as DPI, bitdepth, or paper size easier.
|
||||
More of these extensions may come in later versions.
|
||||
```
|
||||
#!c#
|
||||
|
||||
// choose and open a source
|
||||
IEnumerable<TwainSources> sources = session.GetSources();
|
||||
var myDS = sources.First();
|
||||
myDS.Open();
|
||||
|
||||
```
|
||||
|
||||
At this point you can negotiate with the source using all the typical TWAIN triplet API.
|
||||
The TwainSource class itself has some handy pre-defined methods for common capability negotiation
|
||||
such as DPI, bitdepth, or paper size to get you started.
|
||||
|
||||
When you're ready to get into transfer mode, just call StartTransfer() on the source object.
|
||||
|
||||
```
|
||||
#!c#
|
||||
|
||||
var myDS = sources.StartTransfer(...);
|
||||
|
||||
```
|
||||
|
||||
After transfer has completed (you are notified of this with the SourceDisabled event from session)
|
||||
and you're done with TWAIN, you can close the source and the session in sequence to clean things up.
|
||||
|
||||
```
|
||||
#!c#
|
||||
|
||||
myDS.Close();
|
||||
session.Close();
|
||||
|
||||
```
|
||||
|
||||
|
||||
Caveats
|
||||
--------------------------------------
|
||||
@ -74,12 +97,9 @@ At the moment this lib does not provide ways to parse transferred image data and
|
||||
consumers to do the conversion themselves. The winform project contains one such
|
||||
example for handling DIB image in native transfer using the CommonWin32 lib.
|
||||
|
||||
Because it hosts its own message thread, the events will likely be raised from another thread.
|
||||
Because it hosts its own message thread, the events will be raised from another thread.
|
||||
If you would like things marshalled to a UI thread then set the SynchronizationContext property
|
||||
to the one from the UI thread. Note that on certain consumer-grade scanner drivers this may hang the
|
||||
event, so if you find yourself in that position you'll have to find another way
|
||||
to synchronize data to UI threads.
|
||||
|
||||
to the one from the UI thread.
|
||||
|
||||
```
|
||||
#!c#
|
||||
@ -87,17 +107,18 @@ to synchronize data to UI threads.
|
||||
session.SynchronizationContext = SynchronizationContext.Current;
|
||||
|
||||
```
|
||||
Note that on certain scanner drivers this may hang the
|
||||
application due to their use of modal dialogs, so if you find yourself in that position
|
||||
you'll have to find another way to synchronize data to UI threads.
|
||||
|
||||
|
||||
64-bit OS
|
||||
--------------------------------------
|
||||
If the application process is running in 64-bit then you will need to make sure you have the
|
||||
newer data source manager (twaindsm.dll) from below installed.
|
||||
|
||||
[DSM from TWAIN.org](http://sourceforge.net/projects/twain-dsm/files/TWAIN%20DSM%202%20Win/)
|
||||
|
||||
Otherwise just compile and run the app as x86 and it'll use the 32-bit version (twain_32.dll) that comes with Windows.
|
||||
|
||||
Note that there are no known 64-bit TWAIN DS drivers at the time of writing, so most likely you will have to
|
||||
compile the application as x86 or run on 32-bit OS to work with a real device.
|
||||
If you really want to test in 64-bit for whatever reason, you can use
|
||||
the test one from TWAIN.org below.
|
||||
[Sample DS from TWAIN.org](http://sourceforge.net/projects/twain-samples/files/TWAIN%202%20Sample%20Data%20Source/TWAIN%20DS%202.1.3/)
|
||||
If your scanner driver is still 32-bit (and most likely it will be) you'll have no choice but to
|
||||
compile as x86 anyway, even if you have installed the newer dsm dll.
|
||||
|
Loading…
Reference in New Issue
Block a user