Fix build errors and warnings.

This commit is contained in:
Eugene Wang
2025-11-20 20:46:15 -05:00
parent 1173c11961
commit 2ae7293c44
7 changed files with 398 additions and 471 deletions

View File

@@ -36,11 +36,11 @@ namespace ScannerTester
//_ = _twain.OpenDSMAsync();
}
protected override void OnClosed(EventArgs e)
protected override void OnFormClosed(FormClosedEventArgs e)
{
_twain.CloseDSM();
//_ = _twain.CloseDSMAsync();
base.OnClosed(e);
base.OnFormClosed(e);
}
private void _twain_Transferred(TwainAppSession sender, TransferredEventArgs e)
@@ -196,14 +196,14 @@ namespace ScannerTester
});
}
protected override void OnClosing(CancelEventArgs e)
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (_twain.State > STATE.S5)
{
e.Cancel = true;
}
_twain.TryStepdown(STATE.S2);
base.OnClosing(e);
base.OnFormClosing(e);
}
private void btnSelectScanner_Click(object sender, EventArgs e)
@@ -247,7 +247,7 @@ namespace ScannerTester
private void LoadSettings()
{
var mechs = _twain.Caps.ICAP_XFERMECH.Get();
var mechs = _twain.Caps.ICAP_XFERMECH.Get().GetValues();
if (!mechs.Contains(TWSX.FILE))
{
@@ -263,7 +263,7 @@ namespace ScannerTester
LogIt("Set unit to inches", sts);
}
var dpis = _twain.Caps.ICAP_XRESOLUTION.Get();
var dpis = _twain.Caps.ICAP_XRESOLUTION.Get().GetValues();
listDpi.Items.Clear();
if (dpis.Contains(200))
{
@@ -284,7 +284,7 @@ namespace ScannerTester
LogIt("300 DPI doesn't appear to be supported.");
}
var formats = _twain.Caps.ICAP_IMAGEFILEFORMAT.Get();
var formats = _twain.Caps.ICAP_IMAGEFILEFORMAT.Get().GetValues();
listFormat.Items.Clear();
foreach (var format in formats)
{

View File

@@ -1,17 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationManifest>app.manifest</ApplicationManifest>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<PlatformTarget>x86</PlatformTarget>
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
<ApplicationVisualStyles>true</ApplicationVisualStyles>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NTwain\NTwain.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NTwain\NTwain.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel element will disable file and registry virtualization.
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config.
Makes the application long-path aware. See https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

View File

@@ -1,5 +1,6 @@
using Microsoft.Win32;
using NTwain;
using NTwain.Caps;
using NTwain.Data;
using System;
using System.Collections.Generic;
@@ -14,10 +15,10 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormSample
namespace WinFormSample;
public partial class Form1 : Form
{
public partial class Form1 : Form
{
bool useDiyPump = true;
TwainAppSession twain;
readonly string saveFolder;
@@ -31,275 +32,277 @@ namespace WinFormSample
public Form1()
{
InitializeComponent();
var libVer = FileVersionInfo.GetVersionInfo(typeof(TwainAppSession).Assembly.Location).ProductVersion;
Text += $"{(TWPlatform.Is32bit ? " 32bit" : " 64bit")} on NTwain {libVer}";
InitializeComponent();
var libVer = FileVersionInfo.GetVersionInfo(typeof(TwainAppSession).Assembly.Location).ProductVersion;
Text += $"{(TWPlatform.Is32bit ? " 32bit" : " 64bit")} on NTwain {libVer}";
TWPlatform.PreferLegacyDSM = false;
TWPlatform.PreferLegacyDSM = false;
twain = new TwainAppSession();
twain.StateChanged += Twain_StateChanged;
twain.DefaultSourceChanged += Twain_DefaultSourceChanged;
twain.CurrentSourceChanged += Twain_CurrentSourceChanged;
twain.SourceDisabled += Twain_SourceDisabled;
twain.TransferReady += Twain_TransferReady;
twain.Transferred += Twain_Transferred;
twain.TransferError += Twain_TransferError;
twain.DeviceEvent += Twain_DeviceEvent;
twain = new TwainAppSession();
twain.StateChanged += Twain_StateChanged;
twain.DefaultSourceChanged += Twain_DefaultSourceChanged;
twain.CurrentSourceChanged += Twain_CurrentSourceChanged;
twain.SourceDisabled += Twain_SourceDisabled;
twain.TransferReady += Twain_TransferReady;
twain.Transferred += Twain_Transferred;
twain.TransferError += Twain_TransferError;
twain.DeviceEvent += Twain_DeviceEvent;
capListView.SetDoubleBufferedAsNeeded();
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
capListView.SetDoubleBufferedAsNeeded();
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
saveFolder = Path.Combine(Path.GetTempPath(), "ntwain-sample" + Path.DirectorySeparatorChar);
Directory.CreateDirectory(saveFolder);
saveFolder = Path.Combine(Path.GetTempPath(), "ntwain-sample" + Path.DirectorySeparatorChar);
Directory.CreateDirectory(saveFolder);
this.Disposed += Form1_Disposed;
this.Disposed += Form1_Disposed;
_jpegParameters = new EncoderParameters(1);
_jpegParameters.Param[0] = new EncoderParameter(Encoder.Quality, (long)_jpegQuality);
_jpegEncoder = ImageCodecInfo.GetImageEncoders().First(enc => enc.FormatID == ImageFormat.Jpeg.Guid);
_jpegParameters = new EncoderParameters(1);
_jpegParameters.Param[0] = new EncoderParameter(Encoder.Quality, (long)_jpegQuality);
_jpegEncoder = ImageCodecInfo.GetImageEncoders().First(enc => enc.FormatID == ImageFormat.Jpeg.Guid);
}
private void Twain_SourceDisabled(TwainAppSession sender, TW_IDENTITY_LEGACY e)
{
BeginInvoke(() =>
{
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)
{
switch (e.Reason)
{
case SessionSwitchReason.RemoteConnect:
case SessionSwitchReason.SessionUnlock:
case SessionSwitchReason.SessionLogon:
capListView.SetDoubleBufferedAsNeeded();
break;
}
switch (e.Reason)
{
case SessionSwitchReason.RemoteConnect:
case SessionSwitchReason.SessionUnlock:
case SessionSwitchReason.SessionLogon:
capListView.SetDoubleBufferedAsNeeded();
break;
}
}
protected override async void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
base.OnHandleCreated(e);
if (useDiyPump)
{
var sts = await twain.OpenDSMAsync();
Debug.WriteLine($"OpenDSMAsync={sts}");
}
else
{
var hwnd = this.Handle;
var sts = twain.OpenDSM(hwnd, SynchronizationContext.Current!);
twain.AddWinformFilter();
Debug.WriteLine($"OpenDSM={sts}");
}
if (useDiyPump)
{
var sts = await twain.OpenDSMAsync();
Debug.WriteLine($"OpenDSMAsync={sts}");
}
else
{
var hwnd = this.Handle;
var sts = twain.OpenDSM(hwnd, SynchronizationContext.Current!);
twain.AddWinformFilter();
Debug.WriteLine($"OpenDSM={sts}");
}
}
protected override void OnClosing(CancelEventArgs e)
protected override void OnFormClosing(FormClosingEventArgs e)
{
var finalState = twain.TryStepdown(STATE.S2);
Debug.WriteLine($"Stepdown result state={finalState}");
twain.RemoveWinformFilter();
base.OnClosing(e);
var finalState = twain.TryStepdown(STATE.S2);
Debug.WriteLine($"Stepdown result state={finalState}");
twain.RemoveWinformFilter();
base.OnFormClosing(e);
}
private void Form1_Disposed(object? sender, EventArgs e)
{
twain.Dispose();
twain.Dispose();
}
private void Twain_DeviceEvent(TwainAppSession sender, TW_DEVICEEVENT e)
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] device event {e}.");
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] device event {e}.");
}
private void Twain_TransferError(TwainAppSession sender, TransferErrorEventArgs e)
{
if (e.Exception != null)
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer error {e.Exception}.");
}
else
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer error {e.Code}.");
}
if (e.Exception != null)
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer error {e.Exception}.");
}
else
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer error {e.Code}.");
}
}
private void Twain_Transferred(TwainAppSession sender, TransferredEventArgs e)
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] data transferred with info {e.ImageInfo}");
// if using a high-speed scanner, imaging handling could be a bottleneck
// so it's possible to pass the data to another thread while the scanning
// loop happens. Just remember to dispose it after.
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] data transferred with info {e.ImageInfo}");
// if using a high-speed scanner, imaging handling could be a bottleneck
// so it's possible to pass the data to another thread while the scanning
// loop happens. Just remember to dispose it after.
if (_useThreadForImag)
{
// bad thread example but whatev. should use a dedicated thread of some sort for real
Task.Run(() =>
if (_useThreadForImag)
{
HandleTransferredData(e);
});
}
else
{
HandleTransferredData(e);
}
// bad thread example but whatev. should use a dedicated thread of some sort for real
Task.Run(() =>
{
HandleTransferredData(e);
});
}
else
{
HandleTransferredData(e);
}
}
private void HandleTransferredData(TransferredEventArgs e)
{
if (e.Data != null)
{
try
if (e.Data != null)
{
// example of using some lib to handle image data
var saveFile = Path.Combine(saveFolder, (DateTime.Now.Ticks / 1000).ToString());
try
{
// example of using some lib to handle image data
var saveFile = Path.Combine(saveFolder, (DateTime.Now.Ticks / 1000).ToString());
if (_useSystemDrawing)
{
using (var img = Image.FromStream(e.Data.AsStream()))
{
if (img.PixelFormat == System.Drawing.Imaging.PixelFormat.Format1bppIndexed ||
img.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
{
// bw or gray
saveFile += ".png";
if (_saveDisk) img.Save(saveFile, ImageFormat.Png);
else img.Save(new NoOpStream(), ImageFormat.Png);
}
else
{
// color
saveFile += ".jpg";
if (_saveDisk) img.Save(saveFile, _jpegEncoder, _jpegParameters);
else img.Save(new NoOpStream(), _jpegEncoder, _jpegParameters);
}
if (_useSystemDrawing)
{
using (var img = Image.FromStream(e.Data.AsStream()))
{
if (img.PixelFormat == System.Drawing.Imaging.PixelFormat.Format1bppIndexed ||
img.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
{
// bw or gray
saveFile += ".png";
if (_saveDisk) img.Save(saveFile, ImageFormat.Png);
else img.Save(new NoOpStream(), ImageFormat.Png);
}
else
{
// color
saveFile += ".jpg";
if (_saveDisk) img.Save(saveFile, _jpegEncoder, _jpegParameters);
else img.Save(new NoOpStream(), _jpegEncoder, _jpegParameters);
}
}
}
else
{
using (var img = new ImageMagick.MagickImage(e.Data.AsSpan()))
{
var format = ImageMagick.MagickFormat.Png;
if (img.ColorType == ImageMagick.ColorType.Palette)
{
// bw or gray
saveFile += ".png";
}
else
{
// color
saveFile += ".jpg";
format = ImageMagick.MagickFormat.Jpeg;
img.Quality = (uint)_jpegQuality;
}
if (_saveDisk) img.Write(saveFile);
else img.Write(new NoOpStream(), format);
}
Debug.WriteLine($"Saved image to {saveFile}");
}
}
}
else
{
using (var img = new ImageMagick.MagickImage(e.Data.AsSpan()))
catch { }
finally
{
var format = ImageMagick.MagickFormat.Png;
if (img.ColorType == ImageMagick.ColorType.Palette)
{
// bw or gray
saveFile += ".png";
}
else
{
// color
saveFile += ".jpg";
format = ImageMagick.MagickFormat.Jpeg;
img.Quality = (uint)_jpegQuality;
}
if (_saveDisk) img.Write(saveFile);
else img.Write(new NoOpStream(), format);
e.Dispose();
}
Debug.WriteLine($"Saved image to {saveFile}");
}
}
catch { }
finally
{
e.Dispose();
}
}
}
private void Twain_TransferReady(TwainAppSession sender, TransferReadyEventArgs e)
{
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer ready.");
Debug.WriteLine($"[thread {Environment.CurrentManagedThreadId}] transfer ready.");
}
private void Twain_DefaultSourceChanged(TwainAppSession sender, TW_IDENTITY_LEGACY ds)
{
BeginInvoke(() => lblDefault.Text = ds.ProductName);
BeginInvoke(() => lblDefault.Text = ds.ProductName);
}
private void Twain_StateChanged(TwainAppSession sender, STATE state)
{
BeginInvoke(() => lblState.Text = state.ToString());
BeginInvoke(() => lblState.Text = state.ToString());
}
private void Twain_CurrentSourceChanged(TwainAppSession sender, TW_IDENTITY_LEGACY ds)
{
BeginInvoke(() =>
{
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}");
}
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)}");
}
}
else
{
capListView.Items.Clear();
}
});
// 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)}");
}
}
else
{
capListView.Items.Clear();
}
});
}
private void LoadCapInfoList()
{
twain.GetCapValues(CAP.CAP_SUPPORTEDCAPS, out IList<CAP> caps);
twain.GetCapValues(CAP.CAP_EXTENDEDCAPS, out IList<CAP> extended);
foreach (var c in caps)
{
ListViewItem it = new(GetFriendlyName(c));
twain.GetCapValues(CAP.CAP_SUPPORTEDCAPS, out ValueContainer<CAP> capsContainer);
twain.GetCapValues(CAP.CAP_EXTENDEDCAPS, out ValueContainer<CAP> extendedContainer);
var caps = capsContainer.GetValues().ToList();
var extended = extendedContainer.GetValues().ToList();
foreach (var c in caps)
{
ListViewItem it = new(GetFriendlyName(c));
if (twain.GetCapCurrent(c, out TW_CAPABILITY twcap).RC == TWRC.SUCCESS)
{
var enumType = SizeAndConversionUtils.GetEnumType(c);
var realType = twcap.DetermineValueType(twain);
it.SubItems.Add(enumType?.Name.ToString() ?? realType.ToString());
it.SubItems.Add(ReadTypedValue(c, enumType, realType, forCurrent: true));
it.SubItems.Add(ReadTypedValue(c, enumType, realType, forCurrent: false));
if (twain.GetCapCurrent(c, out TW_CAPABILITY twcap).RC == TWRC.SUCCESS)
{
var enumType = SizeAndConversionUtils.GetEnumType(c);
var realType = twcap.DetermineValueType(twain);
it.SubItems.Add(enumType?.Name.ToString() ?? realType.ToString());
it.SubItems.Add(ReadTypedValue(c, enumType, realType, forCurrent: true));
it.SubItems.Add(ReadTypedValue(c, enumType, realType, forCurrent: false));
}
else
{
it.SubItems.Add("");
it.SubItems.Add("");
it.SubItems.Add("");
}
it.SubItems.Add(extended.Contains(c).ToString());
var supports = twain.QueryCapSupport(c);
it.SubItems.Add(supports.ToString());
if (!supports.HasFlag(TWQC.SET)) it.ForeColor = Color.Gray;
capListView.Items.Add(it);
}
else
{
it.SubItems.Add("");
it.SubItems.Add("");
it.SubItems.Add("");
}
it.SubItems.Add(extended.Contains(c).ToString());
var supports = twain.QueryCapSupport(c);
it.SubItems.Add(supports.ToString());
if (!supports.HasFlag(TWQC.SET)) it.ForeColor = Color.Gray;
capListView.Items.Add(it);
}
}
private string GetFriendlyName(CAP c)
{
if (c > CAP.CAP_CUSTOMBASE)
{
return $"{CAP.CAP_CUSTOMBASE} + {c - CAP.CAP_CUSTOMBASE}";
}
return c.ToString();
if (c > CAP.CAP_CUSTOMBASE)
{
return $"{CAP.CAP_CUSTOMBASE} + {c - CAP.CAP_CUSTOMBASE}";
}
return c.ToString();
}
// there may be a better way...
@@ -307,189 +310,188 @@ namespace WinFormSample
private string ReadTypedValue(CAP cap, Type? enumType, TWTY type, bool forCurrent)
{
if (enumType != null)
{
if (forCurrent)
if (enumType != null)
{
var currentMethod = twainMethods
.FirstOrDefault(m => m.Name == nameof(TwainAppSession.GetCapCurrent) && m.IsGenericMethod)!
.MakeGenericMethod(enumType);
var args = new object?[] { cap, null };
currentMethod.Invoke(twain, args);
var values = (System.Collections.IList)args[1]!;
if (values.Count == 1)
{
return values[0]!.ToString()!;
}
else if (values.Count > 1)
{
return string.Join(", ", values);
}
return "";
if (forCurrent)
{
var currentMethod = twainMethods
.FirstOrDefault(m => m.Name == nameof(TwainAppSession.GetCapCurrent) && m.IsGenericMethod)!
.MakeGenericMethod(enumType);
var args = new object?[] { cap, null };
currentMethod.Invoke(twain, args);
var values = (System.Collections.IList)args[1]!;
if (values.Count == 1)
{
return values[0]!.ToString()!;
}
else if (values.Count > 1)
{
return string.Join(", ", values);
}
return "";
}
else
{
var defaultMethod = twainMethods
.FirstOrDefault(m => m.Name == nameof(TwainAppSession.GetCapDefault) && m.IsGenericMethod)!
.MakeGenericMethod(enumType);
var args = new object?[] { cap, null };
defaultMethod.Invoke(twain, args);
var values = (System.Collections.IList)args[1]!;
if (values.Count == 1)
{
return values[0]!.ToString()!;
}
else if (values.Count > 1)
{
return string.Join(", ", values);
}
return "";
}
}
else
{
var defaultMethod = twainMethods
.FirstOrDefault(m => m.Name == nameof(TwainAppSession.GetCapDefault) && m.IsGenericMethod)!
.MakeGenericMethod(enumType);
var args = new object?[] { cap, null };
defaultMethod.Invoke(twain, args);
var values = (System.Collections.IList)args[1]!;
if (values.Count == 1)
{
return values[0]!.ToString()!;
}
else if (values.Count > 1)
{
return string.Join(", ", values);
}
return "";
}
}
STS sts = default;
switch (type)
{
case TWTY.UINT8:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<byte> ubval) :
twain.GetCapDefault(cap, out ubval);
return ubval.FirstOrDefault().ToString();
case TWTY.INT8:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<sbyte> sbval) :
twain.GetCapDefault(cap, out sbval);
return sbval.FirstOrDefault().ToString();
case TWTY.UINT16:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<ushort> usval) :
twain.GetCapDefault(cap, out usval);
return usval.FirstOrDefault().ToString();
case TWTY.INT16:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<short> ssval) :
twain.GetCapDefault(cap, out ssval);
return ssval.FirstOrDefault().ToString();
case TWTY.UINT32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<uint> uival) :
twain.GetCapDefault(cap, out uival);
return uival.FirstOrDefault().ToString();
case TWTY.INT32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<int> sival) :
twain.GetCapDefault(cap, out sival);
return sival.FirstOrDefault().ToString();
case TWTY.BOOL:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_BOOL> tbval) :
twain.GetCapDefault(cap, out tbval);
return tbval.FirstOrDefault().ToString();
case TWTY.FIX32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_FIX32> fxval) :
twain.GetCapDefault(cap, out fxval);
return fxval.FirstOrDefault().ToString();
case TWTY.FRAME:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_FRAME> frval) :
twain.GetCapDefault(cap, out frval);
return frval.FirstOrDefault().ToString();
case TWTY.STR32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR32> s32val) :
twain.GetCapDefault(cap, out s32val);
return s32val.FirstOrDefault().ToString();
case TWTY.STR64:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR64> s64val) :
twain.GetCapDefault(cap, out s64val);
return s64val.FirstOrDefault().ToString();
case TWTY.STR128:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR128> s128val) :
twain.GetCapDefault(cap, out s128val);
return s128val.FirstOrDefault().ToString();
case TWTY.STR255:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR255> s255val) :
twain.GetCapDefault(cap, out s255val);
return s255val.FirstOrDefault().ToString();
case TWTY.HANDLE:
break;
}
Debug.WriteLine($"{nameof(ReadTypedValue)}({cap}, {type}, {forCurrent}) => {sts}");
return "";
STS sts = default;
switch (type)
{
case TWTY.UINT8:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<byte> ubval) :
twain.GetCapDefault(cap, out ubval);
return ubval.FirstOrDefault().ToString();
case TWTY.INT8:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<sbyte> sbval) :
twain.GetCapDefault(cap, out sbval);
return sbval.FirstOrDefault().ToString();
case TWTY.UINT16:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<ushort> usval) :
twain.GetCapDefault(cap, out usval);
return usval.FirstOrDefault().ToString();
case TWTY.INT16:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<short> ssval) :
twain.GetCapDefault(cap, out ssval);
return ssval.FirstOrDefault().ToString();
case TWTY.UINT32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<uint> uival) :
twain.GetCapDefault(cap, out uival);
return uival.FirstOrDefault().ToString();
case TWTY.INT32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<int> sival) :
twain.GetCapDefault(cap, out sival);
return sival.FirstOrDefault().ToString();
case TWTY.BOOL:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_BOOL> tbval) :
twain.GetCapDefault(cap, out tbval);
return tbval.FirstOrDefault().ToString();
case TWTY.FIX32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_FIX32> fxval) :
twain.GetCapDefault(cap, out fxval);
return fxval.FirstOrDefault().ToString();
case TWTY.FRAME:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_FRAME> frval) :
twain.GetCapDefault(cap, out frval);
return frval.FirstOrDefault().ToString();
case TWTY.STR32:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR32> s32val) :
twain.GetCapDefault(cap, out s32val);
return s32val.FirstOrDefault().ToString();
case TWTY.STR64:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR64> s64val) :
twain.GetCapDefault(cap, out s64val);
return s64val.FirstOrDefault().ToString();
case TWTY.STR128:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR128> s128val) :
twain.GetCapDefault(cap, out s128val);
return s128val.FirstOrDefault().ToString();
case TWTY.STR255:
sts = forCurrent ?
twain.GetCapCurrent(cap, out List<TW_STR255> s255val) :
twain.GetCapDefault(cap, out s255val);
return s255val.FirstOrDefault().ToString();
case TWTY.HANDLE:
break;
}
Debug.WriteLine($"{nameof(ReadTypedValue)}({cap}, {type}, {forCurrent}) => {sts}");
return "";
}
private void btnSelect_Click(object sender, EventArgs e)
{
twain.ShowUserSelect();
twain.ShowUserSelect();
}
private void btnEnumSources_Click(object sender, EventArgs e)
{
listSources.Items.Clear();
foreach (var ds in twain.GetSources())
{
listSources.Items.Add(ds);
}
listSources.Items.Clear();
foreach (var ds in twain.GetSources())
{
listSources.Items.Add(ds);
}
}
private void btnSetDef_Click(object sender, EventArgs e)
{
if (listSources.SelectedItem is TW_IDENTITY_LEGACY ds)
{
twain.SetDefaultSource(ds);
}
if (listSources.SelectedItem is TW_IDENTITY_LEGACY ds)
{
twain.SetDefaultSource(ds);
}
}
private void btnOpen_Click(object sender, EventArgs e)
{
if (listSources.SelectedItem is TW_IDENTITY_LEGACY ds)
{
twain.TryStepdown(STATE.S3);
if (listSources.SelectedItem is TW_IDENTITY_LEGACY ds)
{
twain.TryStepdown(STATE.S3);
twain.OpenSource(ds);
}
twain.OpenSource(ds);
}
}
private void btnClose_Click(object sender, EventArgs e)
{
twain.CloseSource();
twain.CloseSource();
}
private void btnOpenDef_Click(object sender, EventArgs e)
{
twain.TryStepdown(STATE.S3);
twain.TryStepdown(STATE.S3);
twain.OpenSource(twain.DefaultSource);
twain.OpenSource(twain.DefaultSource);
}
private void btnShowSettings_Click(object sender, EventArgs e)
{
twain.EnableSource(true, true);
twain.EnableSource(true, true);
}
private void btnStart_Click(object sender, EventArgs e)
{
if (twain.EnableSource(ckShowUI.Checked, false).IsSuccess)
{
_useThreadForImag = ckBgImageHandling.Checked;
_useSystemDrawing = ckSystemDrawing.Checked;
_saveDisk = ckSaveDisk.Checked;
watch.Restart();
}
if (twain.EnableSource(ckShowUI.Checked, false).IsSuccess)
{
_useThreadForImag = ckBgImageHandling.Checked;
_useSystemDrawing = ckSystemDrawing.Checked;
_saveDisk = ckSaveDisk.Checked;
watch.Restart();
}
}
private void btnOpenFolder_Click(object sender, EventArgs e)
{
try
{
if (!Directory.Exists(saveFolder)) Directory.CreateDirectory(saveFolder);
using (Process.Start(new ProcessStartInfo { FileName = saveFolder, UseShellExecute = true })) { }
}
catch { }
try
{
if (!Directory.Exists(saveFolder)) Directory.CreateDirectory(saveFolder);
using (Process.Start(new ProcessStartInfo { FileName = saveFolder, UseShellExecute = true })) { }
}
catch { }
}
}
}

View File

@@ -6,24 +6,26 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<PlatformTarget>x86</PlatformTarget>
<RootNamespace>WinFormSample</RootNamespace>
<RootNamespace>WinFormSample</RootNamespace>
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
<ApplicationVisualStyles>true</ApplicationVisualStyles>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Magick.NET-Q8-x86" Version="14.9.1" />
<PackageReference Include="Magick.NET-Q8-x86" Version="14.9.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NTwain\NTwain.csproj" />
<ProjectReference Include="..\..\src\NTwain\NTwain.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="platforms\qwindows.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="runtimes\win-x86\native\TWAINDSM.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="platforms\qwindows.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="runtimes\win-x86\native\TWAINDSM.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -1,37 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<PlatformTarget>x64</PlatformTarget>
<RootNamespace>WinFormSample</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<PlatformTarget>x64</PlatformTarget>
<RootNamespace>WinFormSample</RootNamespace>
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
<ApplicationVisualStyles>true</ApplicationVisualStyles>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NTwain\NTwain.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NTwain\NTwain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Magick.NET-Q8-x64" Version="14.9.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Magick.NET-Q8-x64" Version="14.9.1" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\WinForm32\**\*.cs" Exclude="..\WinForm32\**\obj\**;..\WinForm32\**\bin\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<EmbeddedResource Include="..\WinForm32\**\*.resx" Exclude="..\WinForm32\**\obj\**;..\WinForm32\**\bin\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Include="..\WinForm32\**\*.cs" Exclude="..\WinForm32\**\obj\**;..\WinForm32\**\bin\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<EmbeddedResource Include="..\WinForm32\**\*.resx" Exclude="..\WinForm32\**\obj\**;..\WinForm32\**\bin\**">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="platforms\qwindows.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="runtimes\win-x64\native\TWAINDSM.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Update="platforms\qwindows.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="runtimes\win-x64\native\TWAINDSM.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -175,7 +175,7 @@ namespace NTwain
/// </summary>
/// <typeparam name="TValue"></typeparam>
/// <param name="cap"></param>
/// <param name="values"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapValues<TValue>(CAP cap, out ValueContainer<TValue> value) where TValue : struct
{