Test winform integration.

This commit is contained in:
Eugene Wang
2023-04-02 21:15:10 -04:00
parent 4e336ff110
commit 16aaf25f10
7 changed files with 138 additions and 15 deletions

View File

@@ -1,4 +1,3 @@
@echo off
cls
dotnet pack src\NTwain -c Release -o build
dotnet pack src\NTwain.Win -c Release -o build

View File

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

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Runtime.InteropServices;
namespace NTwain.Native
{
/// <summary>
/// The MSG structure in Windows for TWAIN use.
/// </summary>
[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;
}
}

View File

@@ -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

View File

@@ -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)
{
}
}
}

View File

@@ -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(<TwainSession instance>)
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