Made it possible to create event args externally for testing.

This commit is contained in:
soukoku
2014-09-12 07:16:10 -04:00
parent 81710b7e99
commit 0cd02ac16e
10 changed files with 245 additions and 161 deletions

View File

@@ -18,7 +18,7 @@ namespace NTwain
/// <summary>
/// Basic class for interfacing with TWAIN. You should only have one of this per application process.
/// </summary>
public partial class TwainSession : ITwainSessionInternal, IWinMessageFilter
public partial class TwainSession
{
/// <summary>
/// Initializes a new instance of the <see cref="TwainSession"/> class.
@@ -557,114 +557,5 @@ namespace NTwain
protected virtual void OnTransferError(TransferErrorEventArgs e) { }
#endregion
#region handle twain ds message
#region IWinMessageFilter Members
/// <summary>
/// Checks and handle the message if it's a TWAIN message.
/// </summary>
/// <param name="hwnd">The window handle.</param>
/// <param name="msg">The message.</param>
/// <param name="wParam">The w parameter.</param>
/// <param name="lParam">The l parameter.</param>
/// <returns>
/// true if handled internally.
/// </returns>
public bool IsTwainMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
{
bool handled = false;
// this handles the message from a typical WndProc message loop and check if it's from the TWAIN source.
if (_state >= 5)
{
// transform it into a pointer for twain
IntPtr msgPtr = IntPtr.Zero;
try
{
var winMsg = new NTwain.Internals.MESSAGE(hwnd, msg, wParam, lParam);
// no need to do another lock call when using marshal alloc
msgPtr = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
Marshal.StructureToPtr(winMsg, msgPtr, false);
var evt = new TWEvent();
evt.pEvent = msgPtr;
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));
HandleSourceMsg(evt.TWMessage);
}
}
finally
{
if (msgPtr != IntPtr.Zero) { Marshal.FreeHGlobal(msgPtr); }
}
}
return handled;
}
#endregion
ReturnCode HandleCallback(TWIdentity origin, TWIdentity destination, DataGroups dg, DataArgumentType dat, Message msg, IntPtr data)
{
if (origin != null && CurrentSource != null && origin.Id == CurrentSource.Identity.Id && _state >= 5)
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CallbackHandler at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, msg));
// spec says we must handle this on the thread that enabled the DS.
// by using the internal dispatcher this will be the case.
_msgLoopHook.BeginInvoke(() =>
{
HandleSourceMsg(msg);
});
return ReturnCode.Success;
}
return ReturnCode.Failure;
}
// final method that handles msg from the source, whether it's from wndproc or callbacks
void HandleSourceMsg(Message msg)
{
switch (msg)
{
case Message.XferReady:
if (State < 6)
{
State = 6;
}
TransferLogic.DoTransferRoutine(this);
break;
case Message.DeviceEvent:
TWDeviceEvent de;
var rc = ((ITwainSessionInternal)this).DGControl.DeviceEvent.Get(out de);
if (rc == ReturnCode.Success)
{
SafeSyncableRaiseOnEvent(OnDeviceEvent, DeviceEvent, new DeviceEventArgs(de));
}
break;
case Message.CloseDSReq:
case Message.CloseDSOK:
Debug.WriteLine("Got msg " + msg);
// 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
((ITwainSessionInternal)this).DisableSource();
}
break;
}
}
#endregion
}
}