mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
Made it possible to create event args externally for testing.
This commit is contained in:
parent
81710b7e99
commit
0cd02ac16e
@ -1730,12 +1730,13 @@ namespace NTwain.Data
|
||||
public string ProductName { get { return _productName; } set { value.VerifyLengthUnder(TwainConst.String32 - 1); _productName = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="TWIdentity"/> from assembly values.
|
||||
/// Creates a <see cref="TWIdentity" /> from assembly values.
|
||||
/// </summary>
|
||||
/// <param name="supportedGroups">The supported groups.</param>
|
||||
/// <param name="assembly">The assembly.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException">assembly</exception>
|
||||
/// <exception cref="System.ArgumentNullException">assembly</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
public static TWIdentity CreateFromAssembly(DataGroups supportedGroups, Assembly assembly)
|
||||
{
|
||||
if (assembly == null) { throw new ArgumentNullException("assembly"); }
|
||||
@ -1755,10 +1756,16 @@ namespace NTwain.Data
|
||||
/// <param name="productName">Name of the product.</param>
|
||||
/// <param name="productDescription">The product description.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException">version</exception>
|
||||
/// <exception cref="System.ArgumentNullException">assembly</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
public static TWIdentity Create(DataGroups supportedGroups, Version version,
|
||||
string manufacturer, string productFamily, string productName, string productDescription)
|
||||
{
|
||||
if ((supportedGroups & DataGroups.Image) == 0 &&
|
||||
(supportedGroups & DataGroups.Audio) == 0)
|
||||
{
|
||||
throw new ArgumentException(Resources.BadDataGroupsForAppId);
|
||||
}
|
||||
if (version == null) { throw new ArgumentNullException("version"); }
|
||||
|
||||
return new TWIdentity
|
||||
|
@ -8,6 +8,37 @@ namespace NTwain
|
||||
/// </summary>
|
||||
public class DataTransferredEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTransferredEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="nativeData">The native data.</param>
|
||||
/// <param name="imageInfo">The image information.</param>
|
||||
public DataTransferredEventArgs(IntPtr nativeData, TWImageInfo imageInfo)
|
||||
{
|
||||
NativeData = nativeData;
|
||||
ImageInfo = imageInfo;
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTransferredEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileDataPath">The file data path.</param>
|
||||
/// <param name="imageInfo">The image information.</param>
|
||||
public DataTransferredEventArgs(string fileDataPath, TWImageInfo imageInfo)
|
||||
{
|
||||
FileDataPath = fileDataPath;
|
||||
ImageInfo = imageInfo;
|
||||
}
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTransferredEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="memoryData">The memory data.</param>
|
||||
/// <param name="imageInfo">The image information.</param>
|
||||
public DataTransferredEventArgs(byte[] memoryData, TWImageInfo imageInfo)
|
||||
{
|
||||
MemoryData = memoryData;
|
||||
ImageInfo = imageInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets pointer to the complete data if the transfer was native.
|
||||
/// The data will be freed once the event handler ends
|
||||
@ -16,7 +47,7 @@ namespace NTwain
|
||||
/// This pointer is already locked for the duration of this event.
|
||||
/// </summary>
|
||||
/// <value>The data pointer.</value>
|
||||
public IntPtr NativeData { get; internal set; }
|
||||
public IntPtr NativeData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file path to the complete data if the transfer was file or memory-file.
|
||||
@ -24,7 +55,7 @@ namespace NTwain
|
||||
/// <value>
|
||||
/// The file path.
|
||||
/// </value>
|
||||
public string FileDataPath { get; internal set; }
|
||||
public string FileDataPath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw memory data if the transfer was memory.
|
||||
@ -35,7 +66,7 @@ namespace NTwain
|
||||
/// The memory data.
|
||||
/// </value>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||
public byte[] MemoryData { get; internal set; }
|
||||
public byte[] MemoryData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the final image information if applicable.
|
||||
@ -43,7 +74,7 @@ namespace NTwain
|
||||
/// <value>
|
||||
/// The final image information.
|
||||
/// </value>
|
||||
public TWImageInfo ImageInfo { get; internal set; }
|
||||
public TWImageInfo ImageInfo { get; private set; }
|
||||
|
||||
///// <summary>
|
||||
///// Gets the extended image information if applicable.
|
||||
|
@ -39,14 +39,7 @@ namespace NTwain.Internals
|
||||
}
|
||||
|
||||
// ask consumer for xfer details
|
||||
var preXferArgs = new TransferReadyEventArgs
|
||||
{
|
||||
AudioInfo = audInfo,
|
||||
PendingImageInfo = imgInfo,
|
||||
PendingTransferCount = pending.Count,
|
||||
EndOfJob = pending.EndOfJob == 0
|
||||
};
|
||||
|
||||
var preXferArgs = new TransferReadyEventArgs(pending.Count, pending.EndOfJob == 0, imgInfo, audInfo); ;
|
||||
session.SafeSyncableRaiseEvent(preXferArgs);
|
||||
|
||||
#endregion
|
||||
@ -144,16 +137,16 @@ namespace NTwain.Internals
|
||||
lockedPtr = Platform.MemoryManager.Lock(dataPtr);
|
||||
}
|
||||
|
||||
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs { NativeData = lockedPtr });
|
||||
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs(lockedPtr, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { ReturnCode = xrc, SourceStatus = session.CurrentSource.GetStatus() });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { Exception = ex });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(ex));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -184,11 +177,11 @@ namespace NTwain.Internals
|
||||
var xrc = session.DGAudio.AudioFileXfer.Get();
|
||||
if (xrc == ReturnCode.XferDone)
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs { FileDataPath = filePath });
|
||||
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs(filePath, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { ReturnCode = xrc, SourceStatus = session.CurrentSource.GetStatus() });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,12 +207,12 @@ namespace NTwain.Internals
|
||||
}
|
||||
else
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { ReturnCode = xrc, SourceStatus = session.CurrentSource.GetStatus() });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { Exception = ex });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(ex));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -254,7 +247,7 @@ namespace NTwain.Internals
|
||||
}
|
||||
else
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { ReturnCode = xrc, SourceStatus = session.CurrentSource.GetStatus() });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,13 +310,13 @@ namespace NTwain.Internals
|
||||
}
|
||||
else
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { ReturnCode = xrc, SourceStatus = session.CurrentSource.GetStatus() });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { Exception = ex });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(ex));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -396,12 +389,12 @@ namespace NTwain.Internals
|
||||
}
|
||||
else
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { ReturnCode = xrc, SourceStatus = session.CurrentSource.GetStatus() });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(xrc, session.CurrentSource.GetStatus()));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs { Exception = ex });
|
||||
session.SafeSyncableRaiseEvent(new TransferErrorEventArgs(ex));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -425,6 +418,7 @@ namespace NTwain.Internals
|
||||
|
||||
static void DoImageXferredEventRoutine(ITwainSessionInternal session, IntPtr dataPtr, byte[] dataArray, string filePath)
|
||||
{
|
||||
DataTransferredEventArgs args = null;
|
||||
TWImageInfo imgInfo;
|
||||
//TWExtImageInfo extInfo = null;
|
||||
//if (session.CurrentSource.SupportedCaps.Contains(CapabilityId.ICapExtImageInfo))
|
||||
@ -438,14 +432,19 @@ namespace NTwain.Internals
|
||||
{
|
||||
imgInfo = null;
|
||||
}
|
||||
session.SafeSyncableRaiseEvent(new DataTransferredEventArgs
|
||||
if (dataPtr != IntPtr.Zero)
|
||||
{
|
||||
NativeData = dataPtr,
|
||||
MemoryData = dataArray,
|
||||
FileDataPath = filePath,
|
||||
ImageInfo = imgInfo,
|
||||
//ExImageInfo = extInfo
|
||||
});
|
||||
args = new DataTransferredEventArgs(dataPtr, imgInfo);
|
||||
}
|
||||
else if (dataArray != null)
|
||||
{
|
||||
args = new DataTransferredEventArgs(dataArray, imgInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
args = new DataTransferredEventArgs(filePath, imgInfo);
|
||||
}
|
||||
session.SafeSyncableRaiseEvent(args);
|
||||
//if (extInfo != null) { extInfo.Dispose(); }
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,6 @@ namespace NTwain
|
||||
//{
|
||||
System.Windows.Forms.Application.RemoveMessageFilter(this);
|
||||
_filter = null;
|
||||
Handle = IntPtr.Zero;
|
||||
//});
|
||||
}
|
||||
|
||||
@ -191,9 +190,9 @@ namespace NTwain
|
||||
if (_hooker != null)
|
||||
{
|
||||
_hooker.RemoveHook(FilterMessage);
|
||||
_hooker.Dispose();
|
||||
// cannot really dispose _hook or the window will also dispose
|
||||
//_hooker.Dispose();
|
||||
_hooker = null;
|
||||
Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
17
NTwain/Properties/Resources.Designer.cs
generated
17
NTwain/Properties/Resources.Designer.cs
generated
@ -8,10 +8,10 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace NTwain.Properties
|
||||
{
|
||||
|
||||
|
||||
namespace NTwain.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
@ -60,6 +60,15 @@ namespace NTwain.Properties
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Data group for application must contain either Image or Audio..
|
||||
/// </summary>
|
||||
internal static string BadDataGroupsForAppId {
|
||||
get {
|
||||
return ResourceManager.GetString("BadDataGroupsForAppId", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Invalid value type for {0}..
|
||||
/// </summary>
|
||||
|
@ -112,11 +112,14 @@
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BadDataGroupsForAppId" xml:space="preserve">
|
||||
<value>Data group for application must contain either Image or Audio.</value>
|
||||
</data>
|
||||
<data name="BadValueType" xml:space="preserve">
|
||||
<value>Invalid value type for {0}.</value>
|
||||
</data>
|
||||
|
@ -8,13 +8,33 @@ namespace NTwain
|
||||
/// </summary>
|
||||
public class TransferErrorEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TransferErrorEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="error">The error.</param>
|
||||
public TransferErrorEventArgs(Exception error)
|
||||
{
|
||||
Exception = error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TransferErrorEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <param name="status">The status.</param>
|
||||
public TransferErrorEventArgs(ReturnCode code, TWStatus status)
|
||||
{
|
||||
ReturnCode = code;
|
||||
SourceStatus = status;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the return code from the transfer.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The return code.
|
||||
/// </value>
|
||||
public ReturnCode ReturnCode { get; internal set; }
|
||||
public ReturnCode ReturnCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source status.
|
||||
@ -22,7 +42,7 @@ namespace NTwain
|
||||
/// <value>
|
||||
/// The source status.
|
||||
/// </value>
|
||||
public TWStatus SourceStatus { get; internal set; }
|
||||
public TWStatus SourceStatus { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the exception if the error is from some exception.
|
||||
@ -30,6 +50,6 @@ namespace NTwain
|
||||
/// <value>
|
||||
/// The exception.
|
||||
/// </value>
|
||||
public Exception Exception { get; internal set; }
|
||||
public Exception Exception { get; private set; }
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,21 @@ namespace NTwain
|
||||
/// </summary>
|
||||
public class TransferReadyEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TransferReadyEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pendingCount">The pending count.</param>
|
||||
/// <param name="endOfJob">if set to <c>true</c> [end of job].</param>
|
||||
/// <param name="imageInfo">The image information.</param>
|
||||
/// <param name="audioInfo">The audio information.</param>
|
||||
public TransferReadyEventArgs(int pendingCount, bool endOfJob, TWImageInfo imageInfo, TWAudioInfo audioInfo)
|
||||
{
|
||||
PendingTransferCount = pendingCount;
|
||||
EndOfJob = endOfJob;
|
||||
PendingImageInfo = imageInfo;
|
||||
AudioInfo = audioInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the current transfer should be canceled
|
||||
/// and continue next transfer if there are more data.
|
||||
@ -25,14 +40,14 @@ namespace NTwain
|
||||
/// Gets a value indicating whether current transfer signifies an end of job in TWAIN world.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if transfer is end of job; otherwise, <c>false</c>.</value>
|
||||
public bool EndOfJob { get; internal set; }
|
||||
public bool EndOfJob { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the known pending transfer count. This may not be appilicable
|
||||
/// for certain scanning modes.
|
||||
/// </summary>
|
||||
/// <value>The pending count.</value>
|
||||
public int PendingTransferCount { get; internal set; }
|
||||
public int PendingTransferCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tentative image information for the current transfer if applicable.
|
||||
@ -41,7 +56,7 @@ namespace NTwain
|
||||
/// <value>
|
||||
/// The image info.
|
||||
/// </value>
|
||||
public TWImageInfo PendingImageInfo { get; internal set; }
|
||||
public TWImageInfo PendingImageInfo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the audio information for the current transfer if applicable.
|
||||
@ -49,7 +64,7 @@ namespace NTwain
|
||||
/// <value>
|
||||
/// The audio information.
|
||||
/// </value>
|
||||
public TWAudioInfo AudioInfo { get; internal set; }
|
||||
public TWAudioInfo AudioInfo { get; private set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
@ -13,7 +14,7 @@ namespace NTwain
|
||||
{
|
||||
// for internal pieces since the main twain session file is getting too long
|
||||
|
||||
partial class TwainSession
|
||||
partial class TwainSession : ITwainSessionInternal, IWinMessageFilter
|
||||
{
|
||||
#region ITwainSessionInternal Members
|
||||
|
||||
@ -196,5 +197,114 @@ namespace NTwain
|
||||
|
||||
#endregion
|
||||
|
||||
#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
|
||||
|
||||
#region handle twain ds message
|
||||
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user