First changeset to make internal message loop non-global.

This commit is contained in:
soukoku
2014-05-24 18:39:07 -04:00
parent f69698f90a
commit 61b0e89313
11 changed files with 170 additions and 107 deletions

View File

@@ -14,6 +14,8 @@ namespace NTwain.Internals
/// <returns></returns>
TWIdentity AppId { get; }
MessageLoop SelfMessageLoop { get; }
/// <summary>
/// Gets or sets a value indicating whether calls to triplets will verify the current twain session state.
/// </summary>

View 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;
}
}

View File

@@ -12,18 +12,21 @@ namespace NTwain.Internals
/// </summary>
class MessageLoop
{
static MessageLoop _instance = new MessageLoop();
public static MessageLoop Instance { get { return _instance; } }
Dispatcher _dispatcher;
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)
{
// 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())
{
var loopThread = new Thread(new ThreadStart(() =>
@@ -32,11 +35,11 @@ namespace NTwain.Internals
_dispatcher = Dispatcher.CurrentDispatcher;
if (!Platform.IsOnMono)
{
_hook = new WindowsHook(hook);
_hook = new WindowsHook(filter);
}
hack.Set();
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;
if (_hook != null)
{

View File

@@ -13,10 +13,12 @@ namespace NTwain.Internals
class WindowsHook : IDisposable
{
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.
// the style values are purely guesses here with
// CS_NOCLOSE, WS_DISABLED, and WS_EX_NOACTIVATE
@@ -27,7 +29,6 @@ namespace NTwain.Internals
Handle = win.Handle;
win.AddHook(WndProc);
_win = win;
_hook = hook;
}
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)
{
if (_hook != null)
if (_filter != null)
{
var winmsg = new MESSAGE(hwnd, msg, wParam, lParam);
_hook(ref winmsg, ref handled);
handled = _filter.IsTwainMessage(hwnd, msg, wParam, lParam);
}
return IntPtr.Zero;
}
@@ -52,32 +50,6 @@ namespace NTwain.Internals
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
public void Dispose()