Tweaks to win32 pinvoke signatures.

This commit is contained in:
Eugene Wang
2018-11-23 15:35:31 -05:00
parent ffeef44ac7
commit b23757ebdc
3 changed files with 64 additions and 47 deletions

View File

@@ -13,7 +13,7 @@ namespace NTwain.Data.Win32
struct MSG struct MSG
{ {
public IntPtr hwnd; public IntPtr hwnd;
public int message; public uint message;
public IntPtr wParam; public IntPtr wParam;
public IntPtr lParam; public IntPtr lParam;
int time; int time;

View File

@@ -10,7 +10,7 @@ namespace NTwain.Data.Win32
/// <summary> /// <summary>
/// Enumerated values of window messages. /// Enumerated values of window messages.
/// </summary> /// </summary>
enum WindowMessage enum WindowMessage : uint
{ {
/// <summary> /// <summary>
/// Performs no operation. An application sends the WM_NULL message if it wants to post a message that the recipient window will ignore. /// Performs no operation. An application sends the WM_NULL message if it wants to post a message that the recipient window will ignore.

View File

@@ -19,7 +19,7 @@ namespace NTwain.Threading
{ {
static ushort classAtom; static ushort classAtom;
static IntPtr hInstance; static IntPtr hInstance;
static readonly int dequeMsg = UnsafeNativeMethods.RegisterWindowMessage("WinMsgLoopQueue"); static readonly uint dequeMsg = UnsafeNativeMethods.RegisterWindowMessageW("WinMsgLoopQueue");
const int CW_USEDEFAULT = -1; const int CW_USEDEFAULT = -1;
@@ -32,14 +32,14 @@ namespace NTwain.Threading
UnsafeNativeMethods.PostQuitMessage(0); UnsafeNativeMethods.PostQuitMessage(0);
return IntPtr.Zero; return IntPtr.Zero;
} }
return UnsafeNativeMethods.DefWindowProc(hWnd, msg, wParam, lParam); return UnsafeNativeMethods.DefWindowProcW(hWnd, msg, wParam, lParam);
} }
static void InitGlobal() static void InitGlobal()
{ {
if (classAtom == 0) if (classAtom == 0)
{ {
hInstance = UnsafeNativeMethods.GetModuleHandle(null); hInstance = UnsafeNativeMethods.GetModuleHandleW(null);
var wc = new WNDCLASSEX(); var wc = new WNDCLASSEX();
wc.cbSize = Marshal.SizeOf(wc); wc.cbSize = Marshal.SizeOf(wc);
@@ -58,7 +58,7 @@ namespace NTwain.Threading
wc.lpszClassName = Guid.NewGuid().ToString("n"); wc.lpszClassName = Guid.NewGuid().ToString("n");
wc.hIconSm = IntPtr.Zero; wc.hIconSm = IntPtr.Zero;
classAtom = UnsafeNativeMethods.RegisterClassEx(ref wc); classAtom = UnsafeNativeMethods.RegisterClassExW(ref wc);
if (classAtom == 0) if (classAtom == 0)
{ {
throw new Win32Exception(); throw new Win32Exception();
@@ -99,7 +99,7 @@ namespace NTwain.Threading
{ {
Debug.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: starting msg pump..."); Debug.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: starting msg pump...");
hWnd = UnsafeNativeMethods.CreateWindowEx(WindowStylesEx.WS_EX_LEFT, classAtom, Guid.NewGuid().ToString(), hWnd = UnsafeNativeMethods.CreateWindowExW(WindowStylesEx.WS_EX_LEFT, classAtom, Guid.NewGuid().ToString(),
WindowStyles.WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, WindowStyles.WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
IntPtr.Zero, IntPtr.Zero, hInstance, IntPtr.Zero); IntPtr.Zero, IntPtr.Zero, hInstance, IntPtr.Zero);
if (hWnd == IntPtr.Zero) if (hWnd == IntPtr.Zero)
@@ -119,31 +119,43 @@ namespace NTwain.Threading
startWaiter.Set(); startWaiter.Set();
MSG msg = default; MSG msg = default;
while (!stop && UnsafeNativeMethods.GetMessage(ref msg, IntPtr.Zero, 0, 0)) var msgRes = 0;
try
{ {
UnsafeNativeMethods.TranslateMessage(ref msg); while (!stop &&
if (!session.HandleWindowsMessage(ref msg)) (msgRes = UnsafeNativeMethods.GetMessageW(ref msg, IntPtr.Zero, 0, 0)) > 0)
{ {
if (msg.message == dequeMsg) UnsafeNativeMethods.TranslateMessage(ref msg);
if (!session.HandleWindowsMessage(ref msg))
{ {
if (actionQueue.TryDequeue(out ActionItem work)) if (msg.message == dequeMsg)
{ {
work.DoAction(); if (actionQueue.TryDequeue(out ActionItem work))
if (stop) break; {
work.DoAction();
if (stop) break;
}
}
else
{
UnsafeNativeMethods.DispatchMessageW(ref msg);
} }
}
else
{
UnsafeNativeMethods.DispatchMessage(ref msg);
} }
} }
} }
// clear queue catch
while (actionQueue.TryDequeue(out ActionItem dummy)) { } {
UnsafeNativeMethods.PostQuitMessage(0);
}
finally
{
// clear queue
while (actionQueue.TryDequeue(out ActionItem dummy)) { }
loopThread = null; loopThread = null;
hWnd = IntPtr.Zero; hWnd = IntPtr.Zero;
stop = false; stop = false;
}
} }
})); }));
loopThread.IsBackground = true; loopThread.IsBackground = true;
@@ -198,7 +210,7 @@ namespace NTwain.Threading
using (var waiter = new ManualResetEventSlim()) using (var waiter = new ManualResetEventSlim())
{ {
actionQueue.Enqueue(new ActionItem(waiter, action)); actionQueue.Enqueue(new ActionItem(waiter, action));
UnsafeNativeMethods.PostMessage(hWnd, dequeMsg, IntPtr.Zero, IntPtr.Zero); UnsafeNativeMethods.PostMessageW(hWnd, dequeMsg, IntPtr.Zero, IntPtr.Zero);
waiter.Wait(); waiter.Wait();
} }
} }
@@ -214,7 +226,7 @@ namespace NTwain.Threading
else else
{ {
actionQueue.Enqueue(new ActionItem(action)); actionQueue.Enqueue(new ActionItem(action));
UnsafeNativeMethods.PostMessage(hWnd, dequeMsg, IntPtr.Zero, IntPtr.Zero); UnsafeNativeMethods.PostMessageW(hWnd, dequeMsg, IntPtr.Zero, IntPtr.Zero);
} }
} }
@@ -222,43 +234,48 @@ namespace NTwain.Threading
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods internal static class UnsafeNativeMethods
{ {
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ThrowOnUnmappableChar = true, BestFitMapping = false)] [DllImport("kernel32.dll", CharSet = CharSet.Unicode,
public static extern IntPtr GetModuleHandle(string modName); SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GetModuleHandleW([MarshalAs(UnmanagedType.LPWStr)] string modName);
[DllImport("user32.dll", CharSet = CharSet.Auto)] [DllImport("user32.dll", CharSet = CharSet.Unicode,
[return: MarshalAs(UnmanagedType.Bool)] SetLastError = true, ExactSpelling = true)]
public static extern bool GetMessage([In, Out] ref MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); public static extern int GetMessageW([In, Out] ref MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
[DllImport("user32.dll", CharSet = CharSet.Auto)] [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern bool TranslateMessage([In, Out] ref MSG lpMsg); public static extern int TranslateMessage([In, Out] ref MSG lpMsg);
[DllImport("user32.dll", CharSet = CharSet.Auto)] [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern IntPtr DispatchMessage([In] ref MSG lpmsg); public static extern IntPtr DispatchMessageW([In] ref MSG lpmsg);
[DllImport("user32.dll", CharSet = CharSet.Auto)] [DllImport("user32.dll", CharSet = CharSet.Unicode,
public static extern int PostMessage(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam); SetLastError = true, ExactSpelling = true)]
public static extern int PostMessageW(IntPtr hWnd, uint msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32.dll")] [DllImport("user32.dll", ExactSpelling = true)]
public static extern void PostQuitMessage(int nExitCode); public static extern void PostQuitMessage(int nExitCode);
[DllImport("user32.dll", CharSet = CharSet.Auto)] [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); public static extern IntPtr DefWindowProcW(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, BestFitMapping = false)] [DllImport("user32.dll", CharSet = CharSet.Unicode,
public static extern int RegisterWindowMessage(string msg); SetLastError = true, ExactSpelling = true)]
public static extern uint RegisterWindowMessageW([MarshalAs(UnmanagedType.LPWStr)] string msg);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", CharSet = CharSet.Unicode,
public static extern ushort RegisterClassEx([In] ref WNDCLASSEX lpwcx); SetLastError = true, ExactSpelling = true)]
public static extern ushort RegisterClassExW([In] ref WNDCLASSEX lpwcx);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)] [DllImport("user32.dll", CharSet = CharSet.Unicode,
public static extern IntPtr CreateWindowEx(WindowStylesEx dwExStyle, SetLastError = true, ExactSpelling = true)]
public static extern IntPtr CreateWindowExW(WindowStylesEx dwExStyle,
ushort lpszClassName, ushort lpszClassName,
[MarshalAs(UnmanagedType.LPStr)] string lpszWindowName, [MarshalAs(UnmanagedType.LPTStr)] string lpszWindowName,
WindowStyles style, WindowStyles style,
int x, int y, int width, int height, int x, int y, int width, int height,
IntPtr hWndParent, IntPtr hMenu, IntPtr hInst, IntPtr lpParam); IntPtr hWndParent, IntPtr hMenu, IntPtr hInst, IntPtr lpParam);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true, ExactSpelling = true)]
public static extern bool DestroyWindow(IntPtr hWnd); public static extern bool DestroyWindow(IntPtr hWnd);
} }
} }