diff --git a/NTwain/TwainSessionBase.cs b/NTwain/TwainSessionBase.cs
index 9af9937..5886ff1 100644
--- a/NTwain/TwainSessionBase.cs
+++ b/NTwain/TwainSessionBase.cs
@@ -299,6 +299,7 @@ namespace NTwain
/// if set to true any driver UI will display as modal.
/// The window handle if modal.
/// The
+ /// Windows only.
/// that is required for certain operations.
/// It is recommended you call this method in an UI thread and pass in
///
@@ -307,7 +308,11 @@ namespace NTwain
/// context
public ReturnCode EnableSource(SourceEnableMode mode, bool modal, HandleRef windowHandle, SynchronizationContext context)
{
- if (context == null) { throw new ArgumentNullException("context"); }
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT)
+ {
+ if (context == null) { throw new ArgumentNullException("context"); }
+ }
+
Debug.WriteLine(string.Format("Thread {0}: EnableSource.", Thread.CurrentThread.ManagedThreadId));
_syncer = context;
@@ -456,7 +461,11 @@ namespace NTwain
var hand = StateChanged;
if (hand != null)
{
- hand(this, EventArgs.Empty);
+ try
+ {
+ hand(this, EventArgs.Empty);
+ }
+ catch { }
}
}
@@ -468,7 +477,11 @@ namespace NTwain
var hand = SourceChanged;
if (hand != null)
{
- hand(this, EventArgs.Empty);
+ try
+ {
+ hand(this, EventArgs.Empty);
+ }
+ catch { }
}
}
@@ -480,7 +493,11 @@ namespace NTwain
var hand = SourceDisabled;
if (hand != null)
{
- hand(this, EventArgs.Empty);
+ try
+ {
+ hand(this, EventArgs.Empty);
+ }
+ catch { }
}
}
@@ -493,7 +510,11 @@ namespace NTwain
var hand = DeviceEvent;
if (hand != null)
{
- hand(this, e);
+ try
+ {
+ hand(this, e);
+ }
+ catch { }
}
}
@@ -506,7 +527,11 @@ namespace NTwain
var hand = TransferReady;
if (hand != null)
{
- hand(this, e);
+ try
+ {
+ hand(this, e);
+ }
+ catch { }
}
}
@@ -519,7 +544,11 @@ namespace NTwain
var hand = DataTransferred;
if (hand != null)
{
- hand(this, e);
+ try
+ {
+ hand(this, e);
+ }
+ catch { }
}
}
@@ -534,6 +563,7 @@ namespace NTwain
/// True if handled by TWAIN.
protected bool HandleWndProcMessage(ref MESSAGE message)
{
+ var handled = false;
if (State >= 4) // technically we should only handle on state >= 5 but there might be missed msgs if we wait until state changes after enabling ds
{
// transform it into a pointer for twain
@@ -546,17 +576,16 @@ namespace NTwain
TWEvent evt = new TWEvent();
evt.pEvent = msgPtr;
- var rc = DGControl.Event.ProcessEvent(evt);
- // TODO: not sure what to DAT to pass
- HandleSourceMsg(null, null, DataGroups.Control, DataArgumentType.Null, evt.TWMessage, IntPtr.Zero);
- return rc == ReturnCode.DSEvent;
+ handled = DGControl.Event.ProcessEvent(evt) == ReturnCode.DSEvent;
+
+ HandleSourceMsg(evt.TWMessage);
}
finally
{
if (msgPtr != IntPtr.Zero) { Marshal.FreeHGlobal(msgPtr); }
}
}
- return false;
+ return handled;
}
ReturnCode HandleCallback(TWIdentity origin, TWIdentity destination, DataGroups dg, DataArgumentType dat, Message msg, IntPtr data)
@@ -568,6 +597,7 @@ namespace NTwain
// but it's usually already the same thread and doesn't work (failure + seqError) w/o jumping to another thread and back.
// My guess is the DS needs to see the Success return code first before letting transfer happen
// so this is an hack to make it happen.
+
// TODO: find a better method.
ThreadPool.QueueUserWorkItem(o =>
{
@@ -576,13 +606,13 @@ namespace NTwain
{
_syncer.Send(blah =>
{
- HandleSourceMsg(origin, destination, dg, dat, msg, data);
+ HandleSourceMsg(msg);
}, null);
}
else
{
// no context? better hope for the best!
- HandleSourceMsg(origin, destination, dg, dat, msg, data);
+ HandleSourceMsg(msg);
}
}, _syncer);
return ReturnCode.Success;
@@ -590,16 +620,57 @@ namespace NTwain
return ReturnCode.Failure;
}
- // final method that handles stuff from the source, whether it's from wndproc or callbacks
- protected virtual void HandleSourceMsg(TWIdentity origin, TWIdentity destination, DataGroups dg, DataArgumentType dat, Message msg, IntPtr data)
+ // method that handles msg from the source, whether it's from wndproc or callbacks
+ void HandleSourceMsg(Message msg)
{
if (msg != Message.Null)
{
- Debug.WriteLine(string.Format("Thread {0}: HandleSourceMsg at state {1} with DG={2} DAT={3} MSG={4}.", Thread.CurrentThread.ManagedThreadId, State, dg, dat, msg));
+ Debug.WriteLine(string.Format("Thread {0}: HandleSourceMsg at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, msg));
}
- throw new NotImplementedException();
+ switch (msg)
+ {
+ case Message.XferReady:
+ if (State < 6)
+ {
+ State = 6;
+ }
+ DoTransferRoutine();
+ break;
+ case Message.DeviceEvent:
+ TWDeviceEvent de;
+ var rc = DGControl.DeviceEvent.Get(out de);
+ if (rc == ReturnCode.Success)
+ {
+ OnDeviceEvent(new DeviceEventArgs(de));
+ }
+ break;
+ case Message.CloseDSReq:
+ case Message.CloseDSOK:
+ // even though it says closeDS it's really disable.
+ // dsok is sent if source is enabled with uionly
+ // some sources send this at other states so do a step down
+ if (State > 5)
+ {
+ ForceStepDown(4);
+ }
+ else if (State == 5)
+ {
+ // needs this state check since some source sends this more than once
+ DisableSource();
+ }
+ break;
+ }
+ }
+
+ ///
+ /// Does the TWAIN transfer routine at state 6.
+ ///
+ ///
+ protected virtual void DoTransferRoutine()
+ {
+ throw new NotImplementedException();
}
#endregion
diff --git a/NTwain/TwainSessionOld.cs b/NTwain/TwainSessionOld.cs
index 78adeeb..9217cf7 100644
--- a/NTwain/TwainSessionOld.cs
+++ b/NTwain/TwainSessionOld.cs
@@ -29,7 +29,7 @@ namespace NTwain
///
public TwainSessionOld(TWIdentity appId) : base(appId) { }
- private void DoTransferRoutine()
+ protected override void DoTransferRoutine()
{
TWPendingXfers pending = new TWPendingXfers();
var rc = ReturnCode.Success;
@@ -191,48 +191,6 @@ namespace NTwain
#region messaging use
- protected override void HandleSourceMsg(TWIdentity origin, TWIdentity destination, DataGroups dg, DataArgumentType dat, Values.Message msg, IntPtr data)
- {
- if (msg != Values.Message.Null)
- {
- Debug.WriteLine(string.Format("Thread {0}: HandleSourceMsg at state {1} with DG={2} DAT={3} MSG={4}.", Thread.CurrentThread.ManagedThreadId, State, dg, dat, msg));
- }
- switch (msg)
- {
- case Values.Message.XferReady:
- if (State < 6)
- State = 6;
- // this is the meat of all twain stuff
- DoTransferRoutine();
- break;
- case Values.Message.DeviceEvent:
- TWDeviceEvent de;
- var rc = DGControl.DeviceEvent.Get(out de);
- if (rc == ReturnCode.Success)
- {
- OnDeviceEvent(new DeviceEventArgs(de));
- }
- break;
- case Values.Message.CloseDSReq:
- case Values.Message.CloseDSOK:
- // even though it says closeDS it's really disable.
- // dsok is sent if source is enabled with uionly
-
- // some sources send this at other states so do a step down
- if (State > 5)
- {
- ForceStepDown(4);
- }
- else if (State == 5)
- {
- // needs this state check since some source sends this more than once
- DisableSource();
- }
- break;
- }
- }
-
-
///
/// Message loop processor for winform.
/// Use this by adding the as an .