diff --git a/Build.cmd b/Build.cmd
index e12a27c..3aaa299 100644
--- a/Build.cmd
+++ b/Build.cmd
@@ -1,4 +1,3 @@
@echo off
cls
dotnet pack src\NTwain -c Release -o build
-dotnet pack src\NTwain.Win -c Release -o build
diff --git a/samples/WinForm32/Form1.Designer.cs b/samples/WinForm32/Form1.Designer.cs
index 275e6c9..9a89251 100644
--- a/samples/WinForm32/Form1.Designer.cs
+++ b/samples/WinForm32/Form1.Designer.cs
@@ -41,8 +41,9 @@
lblState = new System.Windows.Forms.Label();
label3 = new System.Windows.Forms.Label();
btnOpenDef = new System.Windows.Forms.Button();
- btnClose = new System.Windows.Forms.Button();
btnShowSettings = new System.Windows.Forms.Button();
+ btnClose = new System.Windows.Forms.Button();
+ btnStart = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
splitContainer1.Panel1.SuspendLayout();
splitContainer1.Panel2.SuspendLayout();
@@ -159,6 +160,7 @@
//
// splitContainer1.Panel2
//
+ splitContainer1.Panel2.Controls.Add(btnStart);
splitContainer1.Panel2.Controls.Add(btnShowSettings);
splitContainer1.Panel2.Controls.Add(btnClose);
splitContainer1.Panel2.Controls.Add(label2);
@@ -195,6 +197,16 @@
btnOpenDef.UseVisualStyleBackColor = true;
btnOpenDef.Click += btnOpenDef_Click;
//
+ // btnShowSettings
+ //
+ btnShowSettings.Location = new System.Drawing.Point(161, 32);
+ btnShowSettings.Name = "btnShowSettings";
+ btnShowSettings.Size = new System.Drawing.Size(132, 23);
+ btnShowSettings.TabIndex = 5;
+ btnShowSettings.Text = "Show settings only";
+ btnShowSettings.UseVisualStyleBackColor = true;
+ btnShowSettings.Click += btnShowSettings_Click;
+ //
// btnClose
//
btnClose.Location = new System.Drawing.Point(13, 32);
@@ -205,15 +217,15 @@
btnClose.UseVisualStyleBackColor = true;
btnClose.Click += btnClose_Click;
//
- // btnShowSettings
+ // btnStart
//
- btnShowSettings.Location = new System.Drawing.Point(161, 32);
- btnShowSettings.Name = "btnShowSettings";
- btnShowSettings.Size = new System.Drawing.Size(132, 23);
- btnShowSettings.TabIndex = 5;
- btnShowSettings.Text = "Show settings only";
- btnShowSettings.UseVisualStyleBackColor = true;
- btnShowSettings.Click += btnShowSettings_Click;
+ btnStart.Location = new System.Drawing.Point(299, 32);
+ btnStart.Name = "btnStart";
+ btnStart.Size = new System.Drawing.Size(132, 23);
+ btnStart.TabIndex = 6;
+ btnStart.Text = "Start acquisition";
+ btnStart.UseVisualStyleBackColor = true;
+ btnStart.Click += btnStart_Click;
//
// Form1
//
@@ -249,5 +261,6 @@
private System.Windows.Forms.Label lblState;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button btnShowSettings;
+ private System.Windows.Forms.Button btnStart;
}
}
\ No newline at end of file
diff --git a/samples/WinForm32/Form1.cs b/samples/WinForm32/Form1.cs
index a89d7ed..cee6df7 100644
--- a/samples/WinForm32/Form1.cs
+++ b/samples/WinForm32/Form1.cs
@@ -46,6 +46,7 @@ namespace WinForm32
var hwnd = this.Handle;
var rc = twain.OpenDSM(hwnd);
+ Application.AddMessageFilter(twain);
Debug.WriteLine($"OpenDSM={rc}");
}
@@ -54,6 +55,7 @@ namespace WinForm32
var finalState = twain.TryStepdown(STATE.S2);
Debug.WriteLine($"Stepdown result state={finalState}");
+ Application.RemoveMessageFilter(twain);
base.OnClosing(e);
}
@@ -105,5 +107,10 @@ namespace WinForm32
{
twain.EnableSource(true, true);
}
+
+ private void btnStart_Click(object sender, EventArgs e)
+ {
+ twain.EnableSource(true, false);
+ }
}
}
\ No newline at end of file
diff --git a/src/NTwain/Native/WIN_MESSAGE.cs b/src/NTwain/Native/WIN_MESSAGE.cs
new file mode 100644
index 0000000..132eb3a
--- /dev/null
+++ b/src/NTwain/Native/WIN_MESSAGE.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace NTwain.Native
+{
+ ///
+ /// The MSG structure in Windows for TWAIN use.
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ struct WIN_MESSAGE
+ {
+ public IntPtr hwnd;
+ public uint message;
+ public IntPtr wParam;
+ public IntPtr lParam;
+ uint _time;
+ int _x;
+ int _y;
+ uint lprivate;
+ }
+}
diff --git a/src/NTwain/Native/WinformPumpTest.cs b/src/NTwain/Native/WinformPumpTest.cs
new file mode 100644
index 0000000..f38dd4d
--- /dev/null
+++ b/src/NTwain/Native/WinformPumpTest.cs
@@ -0,0 +1,14 @@
+#if WINDOWS || NETFRAMEWORK
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NTwain.Native
+{
+ internal class WinformPumpTest
+ {
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/NTwain/TwainSession.Callbacks.cs b/src/NTwain/TwainSession.Callbacks.cs
index 9579514..38a3898 100644
--- a/src/NTwain/TwainSession.Callbacks.cs
+++ b/src/NTwain/TwainSession.Callbacks.cs
@@ -92,6 +92,11 @@ namespace NTwain
case MSG.XFERREADY:
break;
case MSG.DEVICEEVENT:
+ // use diff thread to get it
+ //if (DGControl.DeviceEvent.Get(ref _appIdentity, ref _currentDS, out TW_DEVICEEVENT de) == STS.SUCCESS)
+ //{
+
+ //}
break;
case MSG.CLOSEDSOK:
DisableSource();
@@ -101,10 +106,5 @@ namespace NTwain
break;
}
}
-
- public void HandleWin32Message(uint msg)
- {
-
- }
}
}
diff --git a/src/NTwain/TwainSession.Windows.cs b/src/NTwain/TwainSession.Windows.cs
new file mode 100644
index 0000000..15b164b
--- /dev/null
+++ b/src/NTwain/TwainSession.Windows.cs
@@ -0,0 +1,69 @@
+#if WINDOWS || NETFRAMEWORK
+using NTwain.Data;
+using NTwain.Native;
+using NTwain.Triplets;
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Windows.Forms;
+
+namespace NTwain
+{
+
+ // contains parts for winform/wpf message loop integration
+
+ partial class TwainSession : IMessageFilter
+ {
+ // winform use with Application.AddMessageFilter()
+ bool System.Windows.Forms.IMessageFilter.PreFilterMessage(ref System.Windows.Forms.Message m)
+ {
+ return CheckIfTwainMessage(m.HWnd, m.Msg, m.WParam, m.LParam);
+ }
+
+ // wpf use
+ IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
+ {
+ handled = CheckIfTwainMessage(hwnd, msg, wParam, lParam);
+ return IntPtr.Zero;
+ }
+
+ private bool CheckIfTwainMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
+ {
+ // this handles the message from a typical WndProc message loop and check if it's from the TWAIN source.
+ bool handled = false;
+ if (_state >= Data.STATE.S5)
+ {
+ TW_EVENT evt = default;
+ try
+ {
+ var winMsg = new WIN_MESSAGE
+ {
+ hwnd = hWnd,
+ message = (uint)msg,
+ wParam = wParam,
+ lParam = lParam
+ };
+ // no need to do another lock call when using marshal alloc
+ evt.pEvent = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
+ Marshal.StructureToPtr(winMsg, evt.pEvent, false);
+
+ var rc = DGControl.Event.ProcessEvent(ref _appIdentity, ref _currentDS, ref evt);
+ handled = rc == STS.DSEVENT;
+ if (evt.TWMessage != 0 && (handled || rc == STS.NOTDSEVENT))
+ {
+ Debug.WriteLine("Thread {0}: CheckIfTwainMessage at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, (MSG)evt.TWMessage);
+ HandleSourceMsg((MSG)evt.TWMessage);
+ }
+ }
+ finally
+ {
+ // do we need to free it
+ if (evt.pEvent != IntPtr.Zero) Marshal.FreeHGlobal(evt.pEvent);
+ }
+ }
+ return handled;
+ }
+ }
+}
+#endif
\ No newline at end of file