Experiment with a winform-based msg pump.

This commit is contained in:
Eugene Wang
2023-04-13 22:19:05 -04:00
parent 24d4471e0f
commit 502013ee57
14 changed files with 287 additions and 101 deletions
-38
View File
@@ -1,38 +0,0 @@
using NTwain.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace WinFormSample
{
/// <summary>
/// For demoing loading dsm from custom path in case
/// it's not installed on system and don't want to be
/// placed besides the exe.
/// </summary>
static class DsmLoader
{
static IntPtr __dllPtr;
public static bool TryUseCustomDSM()
{
if (__dllPtr == IntPtr.Zero)
{
var dll = Path.Combine(
Path.GetDirectoryName(Environment.ProcessPath ?? Assembly.GetExecutingAssembly().Location)!,
$@"runtimes\win-{(TWPlatform.Is32bit ? "x86" : "x64")}\native\TWAINDSM.dll");
__dllPtr = LoadLibraryW(dll);
}
return __dllPtr != IntPtr.Zero;
}
[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibraryW([MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
}
}
+55 -33
View File
@@ -18,6 +18,8 @@ namespace WinFormSample
{
public partial class Form1 : Form
{
bool useDiyPump = true;
MessagePumpThread pump;
TwainAppSession twain;
readonly string saveFolder;
readonly Stopwatch watch = new();
@@ -34,9 +36,10 @@ namespace WinFormSample
var libVer = FileVersionInfo.GetVersionInfo(typeof(TwainAppSession).Assembly.Location).ProductVersion;
Text += $"{(TWPlatform.Is32bit ? " 32bit" : " 64bit")} on NTwain {libVer}";
pump = new MessagePumpThread();
TWPlatform.PreferLegacyDSM = false;
twain = new TwainAppSession(SynchronizationContext.Current!, Assembly.GetExecutingAssembly().Location);
twain = new TwainAppSession(Assembly.GetExecutingAssembly().Location);
twain.StateChanged += Twain_StateChanged;
twain.DefaultSourceChanged += Twain_DefaultSourceChanged;
twain.CurrentSourceChanged += Twain_CurrentSourceChanged;
@@ -62,11 +65,14 @@ namespace WinFormSample
private void Twain_SourceDisabled(TwainAppSession sender, TW_IDENTITY_LEGACY e)
{
if (watch.IsRunning)
BeginInvoke(() =>
{
watch.Stop();
MessageBox.Show($"Took {watch.Elapsed} to finish that transfer.");
}
if (watch.IsRunning)
{
watch.Stop();
MessageBox.Show($"Took {watch.Elapsed} to finish that transfer.");
}
});
}
private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
@@ -85,18 +91,31 @@ namespace WinFormSample
{
base.OnHandleCreated(e);
var hwnd = this.Handle;
var rc = twain.OpenDSM(hwnd);
twain.AddWinformFilter();
Debug.WriteLine($"OpenDSM={rc}");
if (useDiyPump)
{
_ = pump.AttachAsync(twain);
}
else
{
var hwnd = this.Handle;
var rc = twain.OpenDSM(hwnd, SynchronizationContext.Current!);
twain.AddWinformFilter();
Debug.WriteLine($"OpenDSM={rc}");
}
}
protected override void OnClosing(CancelEventArgs e)
{
var finalState = twain.TryStepdown(STATE.S2);
Debug.WriteLine($"Stepdown result state={finalState}");
twain.RemoveWinformFilter();
if (useDiyPump)
{
pump.Detatch();
}
else
{
var finalState = twain.TryStepdown(STATE.S2);
Debug.WriteLine($"Stepdown result state={finalState}");
twain.RemoveWinformFilter();
}
base.OnClosing(e);
}
@@ -214,39 +233,42 @@ namespace WinFormSample
private void Twain_DefaultSourceChanged(TwainAppSession sender, TW_IDENTITY_LEGACY ds)
{
lblDefault.Text = ds.ProductName;
BeginInvoke(() => lblDefault.Text = ds.ProductName);
}
private void Twain_StateChanged(TwainAppSession sender, STATE state)
{
Invoke(() => lblState.Text = state.ToString());
BeginInvoke(() => lblState.Text = state.ToString());
}
private void Twain_CurrentSourceChanged(TwainAppSession sender, TW_IDENTITY_LEGACY ds)
{
lblCurrent.Text = ds.ToString();
if (twain.State == STATE.S4)
BeginInvoke(() =>
{
LoadCapInfoList();
lblCurrent.Text = ds.ToString();
if (twain.State == STATE.S4)
{
LoadCapInfoList();
// never seen a driver support these but here it is to test it
if (twain.GetCapLabel(CAP.ICAP_SUPPORTEDSIZES, out string? test).RC == TWRC.SUCCESS)
{
Debug.WriteLine($"Supported sizes label from ds = {test}");
// never seen a driver support these but here it is to test it
if (twain.GetCapLabel(CAP.ICAP_SUPPORTEDSIZES, out string? test).RC == TWRC.SUCCESS)
{
Debug.WriteLine($"Supported sizes label from ds = {test}");
}
if (twain.GetCapHelp(CAP.ICAP_SUPPORTEDSIZES, out string? test2).RC == TWRC.SUCCESS)
{
Debug.WriteLine($"Supported sizes help from ds = {test2}");
}
if (twain.GetCapLabelEnum(CAP.ICAP_SUPPORTEDSIZES, out IList<string>? test3).RC == TWRC.SUCCESS && test3 != null)
{
Debug.WriteLine($"Supported sizes label enum from ds = {string.Join(Environment.NewLine, test3)}");
}
}
if (twain.GetCapHelp(CAP.ICAP_SUPPORTEDSIZES, out string? test2).RC == TWRC.SUCCESS)
else
{
Debug.WriteLine($"Supported sizes help from ds = {test2}");
capListView.Items.Clear();
}
if (twain.GetCapLabelEnum(CAP.ICAP_SUPPORTEDSIZES, out IList<string>? test3).RC == TWRC.SUCCESS && test3 != null)
{
Debug.WriteLine($"Supported sizes label enum from ds = {string.Join(Environment.NewLine, test3)}");
}
}
else
{
capListView.Items.Clear();
}
});
}
private void LoadCapInfoList()
+8 -8
View File
@@ -16,14 +16,14 @@ namespace WinFormSample
[STAThread]
static void Main()
{
if (DsmLoader.TryUseCustomDSM())
{
Debug.WriteLine("Using our own dsm now :)");
}
else
{
Debug.WriteLine("Will attempt to use default dsm :(");
}
//if (DsmLoader.TryUseCustomDSM())
//{
// Debug.WriteLine("Using our own dsm now :)");
//}
//else
//{
// Debug.WriteLine("Will attempt to use default dsm :(");
//}
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.