mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
First changeset to make internal message loop non-global.
This commit is contained in:
parent
f69698f90a
commit
61b0e89313
@ -79,6 +79,9 @@
|
|||||||
<Compile Include="..\NTwain\Internals\ITwainSessionInternal.cs">
|
<Compile Include="..\NTwain\Internals\ITwainSessionInternal.cs">
|
||||||
<Link>Internals\ITwainSessionInternal.cs</Link>
|
<Link>Internals\ITwainSessionInternal.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\Internals\MESSAGE.cs">
|
||||||
|
<Link>Internals\MESSAGE.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\NTwain\Internals\MessageLoop.cs">
|
<Compile Include="..\NTwain\Internals\MessageLoop.cs">
|
||||||
<Link>Internals\MessageLoop.cs</Link>
|
<Link>Internals\MessageLoop.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -103,6 +106,9 @@
|
|||||||
<Compile Include="..\NTwain\ITwainSession.cs">
|
<Compile Include="..\NTwain\ITwainSession.cs">
|
||||||
<Link>ITwainSession.cs</Link>
|
<Link>ITwainSession.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\IWinMessageFilter.cs">
|
||||||
|
<Link>IWinMessageFilter.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\NTwain\Platform.cs">
|
<Compile Include="..\NTwain\Platform.cs">
|
||||||
<Link>Platform.cs</Link>
|
<Link>Platform.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
26
NTwain/IWinMessageFilter.cs
Normal file
26
NTwain/IWinMessageFilter.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NTwain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for checking whether messages from WndProc is a TWAIN message and is handled
|
||||||
|
/// internally.
|
||||||
|
/// </summary>
|
||||||
|
interface IWinMessageFilter
|
||||||
|
{
|
||||||
|
/// <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>
|
||||||
|
bool IsTwainMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -14,6 +14,8 @@ namespace NTwain.Internals
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
TWIdentity AppId { get; }
|
TWIdentity AppId { get; }
|
||||||
|
|
||||||
|
MessageLoop SelfMessageLoop { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether calls to triplets will verify the current twain session state.
|
/// Gets or sets a value indicating whether calls to triplets will verify the current twain session state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
36
NTwain/Internals/MESSAGE.cs
Normal file
36
NTwain/Internals/MESSAGE.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NTwain.Internals
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The MSG structure in Windows for TWAIN use.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct MESSAGE
|
||||||
|
{
|
||||||
|
public MESSAGE(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam)
|
||||||
|
{
|
||||||
|
_hwnd = hwnd;
|
||||||
|
_message = (uint)message;
|
||||||
|
_wParam = wParam;
|
||||||
|
_lParam = lParam;
|
||||||
|
_time = 0;
|
||||||
|
_x = 0;
|
||||||
|
_y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntPtr _hwnd;
|
||||||
|
uint _message;
|
||||||
|
IntPtr _wParam;
|
||||||
|
IntPtr _lParam;
|
||||||
|
uint _time;
|
||||||
|
int _x;
|
||||||
|
int _y;
|
||||||
|
}
|
||||||
|
}
|
@ -12,18 +12,21 @@ namespace NTwain.Internals
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class MessageLoop
|
class MessageLoop
|
||||||
{
|
{
|
||||||
static MessageLoop _instance = new MessageLoop();
|
|
||||||
public static MessageLoop Instance { get { return _instance; } }
|
|
||||||
|
|
||||||
Dispatcher _dispatcher;
|
Dispatcher _dispatcher;
|
||||||
WindowsHook _hook;
|
WindowsHook _hook;
|
||||||
private MessageLoop() { }
|
|
||||||
|
|
||||||
public void EnsureStarted(WindowsHook.WndProcHook hook)
|
public void Stop()
|
||||||
|
{
|
||||||
|
if (_dispatcher != null)
|
||||||
|
{
|
||||||
|
_dispatcher.InvokeShutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Start(IWinMessageFilter filter)
|
||||||
{
|
{
|
||||||
if (_dispatcher == null)
|
if (_dispatcher == null)
|
||||||
{
|
{
|
||||||
// using this terrible hack so the new thread will start running before this function returns
|
// using this hack so the new thread will start running before this function returns
|
||||||
using (var hack = new WrappedManualResetEvent())
|
using (var hack = new WrappedManualResetEvent())
|
||||||
{
|
{
|
||||||
var loopThread = new Thread(new ThreadStart(() =>
|
var loopThread = new Thread(new ThreadStart(() =>
|
||||||
@ -32,11 +35,11 @@ namespace NTwain.Internals
|
|||||||
_dispatcher = Dispatcher.CurrentDispatcher;
|
_dispatcher = Dispatcher.CurrentDispatcher;
|
||||||
if (!Platform.IsOnMono)
|
if (!Platform.IsOnMono)
|
||||||
{
|
{
|
||||||
_hook = new WindowsHook(hook);
|
_hook = new WindowsHook(filter);
|
||||||
}
|
}
|
||||||
hack.Set();
|
hack.Set();
|
||||||
Dispatcher.Run();
|
Dispatcher.Run();
|
||||||
// if for whatever reason it ever gets here make everything uninitialized
|
// if dispatcher shutsdown we'll get here so make everything uninitialized
|
||||||
_dispatcher = null;
|
_dispatcher = null;
|
||||||
if (_hook != null)
|
if (_hook != null)
|
||||||
{
|
{
|
||||||
|
@ -13,10 +13,12 @@ namespace NTwain.Internals
|
|||||||
class WindowsHook : IDisposable
|
class WindowsHook : IDisposable
|
||||||
{
|
{
|
||||||
IDisposable _win;
|
IDisposable _win;
|
||||||
WndProcHook _hook;
|
IWinMessageFilter _filter;
|
||||||
|
|
||||||
public WindowsHook(WndProcHook hook)
|
public WindowsHook(IWinMessageFilter filter)
|
||||||
{
|
{
|
||||||
|
_filter = filter;
|
||||||
|
|
||||||
// hook into windows msg loop for old twain to post msgs.
|
// hook into windows msg loop for old twain to post msgs.
|
||||||
// the style values are purely guesses here with
|
// the style values are purely guesses here with
|
||||||
// CS_NOCLOSE, WS_DISABLED, and WS_EX_NOACTIVATE
|
// CS_NOCLOSE, WS_DISABLED, and WS_EX_NOACTIVATE
|
||||||
@ -27,7 +29,6 @@ namespace NTwain.Internals
|
|||||||
Handle = win.Handle;
|
Handle = win.Handle;
|
||||||
win.AddHook(WndProc);
|
win.AddHook(WndProc);
|
||||||
_win = win;
|
_win = win;
|
||||||
_hook = hook;
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -36,15 +37,12 @@ namespace NTwain.Internals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void WndProcHook(ref MESSAGE winMsg, ref bool handled);
|
|
||||||
|
|
||||||
|
|
||||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||||
{
|
{
|
||||||
if (_hook != null)
|
if (_filter != null)
|
||||||
{
|
{
|
||||||
var winmsg = new MESSAGE(hwnd, msg, wParam, lParam);
|
handled = _filter.IsTwainMessage(hwnd, msg, wParam, lParam);
|
||||||
_hook(ref winmsg, ref handled);
|
|
||||||
}
|
}
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
}
|
||||||
@ -52,32 +50,6 @@ namespace NTwain.Internals
|
|||||||
public IntPtr Handle { get; private set; }
|
public IntPtr Handle { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The MSG structure in Windows for TWAIN use.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct MESSAGE
|
|
||||||
{
|
|
||||||
public MESSAGE(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam)
|
|
||||||
{
|
|
||||||
_hwnd = hwnd;
|
|
||||||
_message = (uint)message;
|
|
||||||
_wParam = wParam;
|
|
||||||
_lParam = lParam;
|
|
||||||
_time = 0;
|
|
||||||
_x = 0;
|
|
||||||
_y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
IntPtr _hwnd;
|
|
||||||
uint _message;
|
|
||||||
IntPtr _wParam;
|
|
||||||
IntPtr _lParam;
|
|
||||||
uint _time;
|
|
||||||
int _x;
|
|
||||||
int _y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IDisposable Members
|
#region IDisposable Members
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
<Compile Include="IMemoryManager.cs" />
|
<Compile Include="IMemoryManager.cs" />
|
||||||
<Compile Include="Internals\ICommittable.cs" />
|
<Compile Include="Internals\ICommittable.cs" />
|
||||||
<Compile Include="Internals\ITwainSessionInternal.cs" />
|
<Compile Include="Internals\ITwainSessionInternal.cs" />
|
||||||
|
<Compile Include="Internals\MESSAGE.cs" />
|
||||||
<Compile Include="Internals\TransferLogic.cs" />
|
<Compile Include="Internals\TransferLogic.cs" />
|
||||||
<Compile Include="Internals\WindowsHook.cs" />
|
<Compile Include="Internals\WindowsHook.cs" />
|
||||||
<Compile Include="Internals\WrappedManualResetEvent.cs" />
|
<Compile Include="Internals\WrappedManualResetEvent.cs" />
|
||||||
@ -68,6 +69,7 @@
|
|||||||
<Compile Include="Internals\WinMemoryManager.cs" />
|
<Compile Include="Internals\WinMemoryManager.cs" />
|
||||||
<Compile Include="Internals\MessageLoop.cs" />
|
<Compile Include="Internals\MessageLoop.cs" />
|
||||||
<Compile Include="Internals\UnsafeNativeMethods.cs" />
|
<Compile Include="Internals\UnsafeNativeMethods.cs" />
|
||||||
|
<Compile Include="IWinMessageFilter.cs" />
|
||||||
<Compile Include="Platform.cs" />
|
<Compile Include="Platform.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
@ -12,8 +12,8 @@ namespace NTwain
|
|||||||
class _NTwainVersionInfo
|
class _NTwainVersionInfo
|
||||||
{
|
{
|
||||||
// keep this same in majors releases
|
// keep this same in majors releases
|
||||||
public const string Release = "1.0.0.0";
|
public const string Release = "2.0.0.0";
|
||||||
// change this for each nuget release
|
// change this for each nuget release
|
||||||
public const string Build = "1.0.2";
|
public const string Build = "2.0.0";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ namespace NTwain
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Basic class for interfacing with TWAIN. You should only have one of this per application process.
|
/// Basic class for interfacing with TWAIN. You should only have one of this per application process.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TwainSession : ITwainSessionInternal
|
public class TwainSession : ITwainSessionInternal, IWinMessageFilter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TwainSession"/> class.
|
/// Initializes a new instance of the <see cref="TwainSession"/> class.
|
||||||
@ -42,13 +42,14 @@ namespace NTwain
|
|||||||
((ITwainSessionInternal)this).ChangeState(1, false);
|
((ITwainSessionInternal)this).ChangeState(1, false);
|
||||||
EnforceState = true;
|
EnforceState = true;
|
||||||
|
|
||||||
MessageLoop.Instance.EnsureStarted(HandleWndProcMessage);
|
_selfMsgLoop = new MessageLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||||
object _callbackObj; // kept around so it doesn't get gc'ed
|
object _callbackObj; // kept around so it doesn't get gc'ed
|
||||||
TWIdentity _appId;
|
TWIdentity _appId;
|
||||||
TWUserInterface _twui;
|
TWUserInterface _twui;
|
||||||
|
|
||||||
|
|
||||||
static readonly Dictionary<string, TwainSource> __ownedSources = new Dictionary<string, TwainSource>();
|
static readonly Dictionary<string, TwainSource> __ownedSources = new Dictionary<string, TwainSource>();
|
||||||
|
|
||||||
@ -62,8 +63,6 @@ namespace NTwain
|
|||||||
return __ownedSources[key] = new TwainSource(session, sourceId);
|
return __ownedSources[key] = new TwainSource(session, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the optional synchronization context.
|
/// Gets or sets the optional synchronization context.
|
||||||
/// This allows events to be raised on the thread
|
/// This allows events to be raised on the thread
|
||||||
@ -77,6 +76,9 @@ namespace NTwain
|
|||||||
|
|
||||||
#region ITwainSessionInternal Members
|
#region ITwainSessionInternal Members
|
||||||
|
|
||||||
|
MessageLoop _selfMsgLoop;
|
||||||
|
MessageLoop ITwainSessionInternal.SelfMessageLoop { get { return _selfMsgLoop; } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the app id used for the session.
|
/// Gets the app id used for the session.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -126,6 +128,46 @@ namespace NTwain
|
|||||||
SafeSyncableRaiseOnEvent(OnTransferReady, TransferReady, e);
|
SafeSyncableRaiseOnEvent(OnTransferReady, TransferReady, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DGAudio _dgAudio;
|
||||||
|
DGAudio ITwainSessionInternal.DGAudio
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_dgAudio == null) { _dgAudio = new DGAudio(this); }
|
||||||
|
return _dgAudio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DGControl _dgControl;
|
||||||
|
DGControl ITwainSessionInternal.DGControl
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_dgControl == null) { _dgControl = new DGControl(this); }
|
||||||
|
return _dgControl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DGImage _dgImage;
|
||||||
|
DGImage ITwainSessionInternal.DGImage
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_dgImage == null) { _dgImage = new DGImage(this); }
|
||||||
|
return _dgImage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DGCustom _dgCustom;
|
||||||
|
DGCustom ITwainSessionInternal.DGCustom
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_dgCustom == null) { _dgCustom = new DGCustom(this); }
|
||||||
|
return _dgCustom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ITwainSession Members
|
#region ITwainSession Members
|
||||||
@ -202,53 +244,6 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ITwainOperation Members
|
|
||||||
|
|
||||||
DGAudio _dgAudio;
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the triplet operations defined for audio data group.
|
|
||||||
/// </summary>
|
|
||||||
DGAudio ITwainSessionInternal.DGAudio
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_dgAudio == null) { _dgAudio = new DGAudio(this); }
|
|
||||||
return _dgAudio;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DGControl _dgControl;
|
|
||||||
DGControl ITwainSessionInternal.DGControl
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_dgControl == null) { _dgControl = new DGControl(this); }
|
|
||||||
return _dgControl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DGImage _dgImage;
|
|
||||||
DGImage ITwainSessionInternal.DGImage
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_dgImage == null) { _dgImage = new DGImage(this); }
|
|
||||||
return _dgImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DGCustom _dgCustom;
|
|
||||||
DGCustom ITwainSessionInternal.DGCustom
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_dgCustom == null) { _dgCustom = new DGCustom(this); }
|
|
||||||
return _dgCustom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the data source manager. This must be the first method used
|
/// 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.
|
/// before using other TWAIN functions. Calls to this must be followed by <see cref="Close"/> when done with a TWAIN session.
|
||||||
@ -256,12 +251,13 @@ namespace NTwain
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public ReturnCode Open()
|
public ReturnCode Open()
|
||||||
{
|
{
|
||||||
|
_selfMsgLoop.Start(this);
|
||||||
var rc = ReturnCode.Failure;
|
var rc = ReturnCode.Failure;
|
||||||
MessageLoop.Instance.Invoke(() =>
|
_selfMsgLoop.Invoke(() =>
|
||||||
{
|
{
|
||||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenManager.", Thread.CurrentThread.ManagedThreadId));
|
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenManager.", Thread.CurrentThread.ManagedThreadId));
|
||||||
|
|
||||||
rc = ((ITwainSessionInternal)this).DGControl.Parent.OpenDsm(MessageLoop.Instance.LoopHandle);
|
rc = ((ITwainSessionInternal)this).DGControl.Parent.OpenDsm(_selfMsgLoop.LoopHandle);
|
||||||
if (rc == ReturnCode.Success)
|
if (rc == ReturnCode.Success)
|
||||||
{
|
{
|
||||||
// if twain2 then get memory management functions
|
// if twain2 then get memory management functions
|
||||||
@ -291,14 +287,15 @@ namespace NTwain
|
|||||||
public ReturnCode Close()
|
public ReturnCode Close()
|
||||||
{
|
{
|
||||||
var rc = ReturnCode.Failure;
|
var rc = ReturnCode.Failure;
|
||||||
MessageLoop.Instance.Invoke(() =>
|
_selfMsgLoop.Invoke(() =>
|
||||||
{
|
{
|
||||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseManager.", Thread.CurrentThread.ManagedThreadId));
|
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseManager.", Thread.CurrentThread.ManagedThreadId));
|
||||||
|
|
||||||
rc = ((ITwainSessionInternal)this).DGControl.Parent.CloseDsm(MessageLoop.Instance.LoopHandle);
|
rc = ((ITwainSessionInternal)this).DGControl.Parent.CloseDsm(_selfMsgLoop.LoopHandle);
|
||||||
if (rc == ReturnCode.Success)
|
if (rc == ReturnCode.Success)
|
||||||
{
|
{
|
||||||
Platform.MemoryManager = null;
|
Platform.MemoryManager = null;
|
||||||
|
_selfMsgLoop.Stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return rc;
|
return rc;
|
||||||
@ -399,7 +396,7 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
var rc = ReturnCode.Failure;
|
var rc = ReturnCode.Failure;
|
||||||
|
|
||||||
MessageLoop.Instance.Invoke(() =>
|
_selfMsgLoop.Invoke(() =>
|
||||||
{
|
{
|
||||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: EnableSource.", Thread.CurrentThread.ManagedThreadId));
|
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: EnableSource.", Thread.CurrentThread.ManagedThreadId));
|
||||||
|
|
||||||
@ -454,7 +451,7 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
var rc = ReturnCode.Failure;
|
var rc = ReturnCode.Failure;
|
||||||
|
|
||||||
MessageLoop.Instance.Invoke(() =>
|
_selfMsgLoop.Invoke(() =>
|
||||||
{
|
{
|
||||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: DisableSource.", Thread.CurrentThread.ManagedThreadId));
|
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: DisableSource.", Thread.CurrentThread.ManagedThreadId));
|
||||||
|
|
||||||
@ -495,7 +492,7 @@ namespace NTwain
|
|||||||
// success, the return status from DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER may
|
// success, the return status from DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER may
|
||||||
// be ignored.
|
// be ignored.
|
||||||
|
|
||||||
MessageLoop.Instance.Invoke(() =>
|
_selfMsgLoop.Invoke(() =>
|
||||||
{
|
{
|
||||||
if (targetState < 7)
|
if (targetState < 7)
|
||||||
{
|
{
|
||||||
@ -668,8 +665,22 @@ namespace NTwain
|
|||||||
|
|
||||||
#region handle twain ds message
|
#region handle twain ds message
|
||||||
|
|
||||||
void HandleWndProcMessage(ref WindowsHook.MESSAGE winMsg, ref bool handled)
|
|
||||||
|
#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.
|
// this handles the message from a typical WndProc message loop and check if it's from the TWAIN source.
|
||||||
if (_state >= 5)
|
if (_state >= 5)
|
||||||
{
|
{
|
||||||
@ -677,6 +688,8 @@ namespace NTwain
|
|||||||
IntPtr msgPtr = IntPtr.Zero;
|
IntPtr msgPtr = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var winMsg = new NTwain.Internals.MESSAGE(hwnd, msg, wParam, lParam);
|
||||||
|
|
||||||
// no need to do another lock call when using marshal alloc
|
// no need to do another lock call when using marshal alloc
|
||||||
msgPtr = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
|
msgPtr = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
|
||||||
Marshal.StructureToPtr(winMsg, msgPtr, false);
|
Marshal.StructureToPtr(winMsg, msgPtr, false);
|
||||||
@ -695,8 +708,11 @@ namespace NTwain
|
|||||||
if (msgPtr != IntPtr.Zero) { Marshal.FreeHGlobal(msgPtr); }
|
if (msgPtr != IntPtr.Zero) { Marshal.FreeHGlobal(msgPtr); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
ReturnCode HandleCallback(TWIdentity origin, TWIdentity destination, DataGroups dg, DataArgumentType dat, Message msg, IntPtr data)
|
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)
|
if (origin != null && CurrentSource != null && origin.Id == CurrentSource.Identity.Id && _state >= 5)
|
||||||
@ -705,7 +721,7 @@ namespace NTwain
|
|||||||
// spec says we must handle this on the thread that enabled the DS.
|
// spec says we must handle this on the thread that enabled the DS.
|
||||||
// by using the internal dispatcher this will be the case.
|
// by using the internal dispatcher this will be the case.
|
||||||
|
|
||||||
MessageLoop.Instance.BeginInvoke(() =>
|
_selfMsgLoop.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
HandleSourceMsg(msg);
|
HandleSourceMsg(msg);
|
||||||
});
|
});
|
||||||
|
@ -32,7 +32,7 @@ namespace NTwain
|
|||||||
public ReturnCode Open()
|
public ReturnCode Open()
|
||||||
{
|
{
|
||||||
var rc = ReturnCode.Failure;
|
var rc = ReturnCode.Failure;
|
||||||
MessageLoop.Instance.Invoke(() =>
|
_session.SelfMessageLoop.Invoke(() =>
|
||||||
{
|
{
|
||||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId));
|
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId));
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ namespace NTwain
|
|||||||
public ReturnCode Close()
|
public ReturnCode Close()
|
||||||
{
|
{
|
||||||
var rc = ReturnCode.Failure;
|
var rc = ReturnCode.Failure;
|
||||||
MessageLoop.Instance.Invoke(() =>
|
_session.SelfMessageLoop.Invoke(() =>
|
||||||
{
|
{
|
||||||
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId));
|
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId));
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ namespace Tester.WPF
|
|||||||
Format = wantFormat,
|
Format = wantFormat,
|
||||||
FileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.tif")
|
FileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.tif")
|
||||||
};
|
};
|
||||||
var rc = this.DGControl.SetupFileXfer.Set(fileSetup);
|
var rc = this.CurrentSource.DGControl.SetupFileXfer.Set(fileSetup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user