mirror of
				https://github.com/soukoku/ntwain.git
				synced 2025-10-31 16:46:51 +08:00 
			
		
		
		
	First changeset to make internal message loop non-global.
This commit is contained in:
		| @@ -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); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 soukoku
					soukoku