5 Commits

Author SHA1 Message Date
Eugene Wang
2ae7293c44 Fix build errors and warnings. 2025-11-20 20:46:15 -05:00
Eugene Wang
1173c11961 Fix wrong cap call for Get. 2025-11-20 20:28:07 -05:00
Eugene Wang
8949b36833 Changed to return value container for available cap value to prevent long range enumerations. 2025-11-20 13:18:21 -05:00
Eugene Wang
36c7dd11ca Fix ICAP_SKEWANGLE value type to int. 2025-11-20 09:18:04 -05:00
Eugene Wang
2167d74fdc Added rest of kodak caps as properties. 2025-11-20 08:52:14 -05:00
15 changed files with 1124 additions and 617 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

@@ -2,7 +2,7 @@
<PropertyGroup>
<!--change these in each release-->
<VersionPrefix>4.0.0.0</VersionPrefix>
<VersionSuffix>alpha.14</VersionSuffix>
<VersionSuffix>alpha.18</VersionSuffix>
<!--keep it the same until major # changes-->
<AssemblyVersion>4.0.0.0</AssemblyVersion>

View File

@@ -4,101 +4,97 @@ using System.Collections.Generic;
namespace NTwain.Caps
{
/// <summary>
///
/// </summary>
/// <typeparam name="TValue"></typeparam>
public class CapReader<TValue> where TValue : struct
{
protected readonly TwainAppSession _twain;
public CapReader(TwainAppSession twain, CAP cap, float introducedVersion = 1)
{
_twain = twain;
Cap = cap;
Introduced = introducedVersion;
}
public CAP Cap { get; }
/// <summary>
/// When this was introduced in TWAIN.
///
/// </summary>
public float Introduced { get; }
/// <summary>
/// The STS result from the most recent call with this cap wrapper.
/// </summary>
public STS LastSTS { get; protected set; }
TWQC? _qc;
public TWQC Supports
/// <typeparam name="TValue"></typeparam>
public class CapReader<TValue> where TValue : struct
{
get
{
if (!_qc.HasValue) _qc = _twain.QueryCapSupport(Cap);
return _qc.Value;
}
}
protected readonly TwainAppSession _twain;
public IList<TValue> Get()
{
LastSTS = _twain.GetCapValues(Cap, out IList<TValue> values);
if (LastSTS.IsSuccess)
{
return values;
};
return Array.Empty<TValue>();
}
public CapReader(TwainAppSession twain, CAP cap, float introducedVersion = 1)
{
_twain = twain;
Cap = cap;
Introduced = introducedVersion;
}
public IList<TValue> GetCurrent()
{
LastSTS = _twain.GetCapCurrent(Cap, out List<TValue> value);
if (LastSTS.IsSuccess)
{
return value;
};
return Array.Empty<TValue>();
}
public CAP Cap { get; }
public IList<TValue> GetDefault()
{
LastSTS = _twain.GetCapDefault(Cap, out List<TValue> value);
if (LastSTS.IsSuccess)
{
return value;
};
return Array.Empty<TValue>();
}
/// <summary>
/// When this was introduced in TWAIN.
/// </summary>
public float Introduced { get; }
public string? GetLabel()
{
LastSTS = _twain.GetCapLabel(Cap, out string? value);
if (LastSTS.IsSuccess)
{
return value;
};
return default;
}
/// <summary>
/// The STS result from the most recent call with this cap wrapper.
/// </summary>
public STS LastSTS { get; protected set; }
public string? GetHelp()
{
LastSTS = _twain.GetCapHelp(Cap, out string? value);
if (LastSTS.IsSuccess)
{
return value;
};
return default;
}
TWQC? _qc;
public TWQC Supports
{
get
{
if (!_qc.HasValue) _qc = _twain.QueryCapSupport(Cap);
return _qc.Value;
}
}
public IList<string> GetLabelEnum()
{
LastSTS = _twain.GetCapLabelEnum(Cap, out IList<string> value);
if (LastSTS.IsSuccess)
{
return value;
};
return Array.Empty<string>();
public ValueContainer<TValue> Get()
{
LastSTS = _twain.GetCapValues(Cap, out ValueContainer<TValue> value);
return value;
}
public IList<TValue> GetCurrent()
{
LastSTS = _twain.GetCapCurrent(Cap, out List<TValue> value);
if (LastSTS.IsSuccess)
{
return value;
}
return Array.Empty<TValue>();
}
public IList<TValue> GetDefault()
{
LastSTS = _twain.GetCapDefault(Cap, out List<TValue> value);
if (LastSTS.IsSuccess)
{
return value;
}
return Array.Empty<TValue>();
}
public string? GetLabel()
{
LastSTS = _twain.GetCapLabel(Cap, out string? value);
if (LastSTS.IsSuccess)
{
return value;
}
return default;
}
public string? GetHelp()
{
LastSTS = _twain.GetCapHelp(Cap, out string? value);
if (LastSTS.IsSuccess)
{
return value;
}
return default;
}
public IList<string> GetLabelEnum()
{
LastSTS = _twain.GetCapLabelEnum(Cap, out IList<string> value);
if (LastSTS.IsSuccess)
{
return value;
}
return Array.Empty<string>();
}
}
}
}

View File

@@ -117,4 +117,190 @@ partial class KdsCaps
public CapWriter<TWCBR> ICAP_COLORBRIGHTNESSMODE =>
_ICAP_COLORBRIGHTNESSMODE ??= new(_twain, (CAP)KDS_CAP.ICAP_COLORBRIGHTNESSMODE, 2);
// TODO: verify data types below
CapWriter<TW_BOOL>? _ICAP_LAMPSAVER;
public CapWriter<TW_BOOL> ICAP_LAMPSAVER =>
_ICAP_LAMPSAVER ??= new(_twain, (CAP)KDS_CAP.ICAP_LAMPSAVER, 2);
CapWriter<TW_FIX32>? _ICAP_OVERSCANX;
public CapWriter<TW_FIX32> ICAP_OVERSCANX =>
_ICAP_OVERSCANX ??= new(_twain, (CAP)KDS_CAP.ICAP_OVERSCANX, 2);
CapWriter<TW_FIX32>? _ICAP_OVERSCANY;
public CapWriter<TW_FIX32> ICAP_OVERSCANY =>
_ICAP_OVERSCANY ??= new(_twain, (CAP)KDS_CAP.ICAP_OVERSCANY, 2);
CapWriter<ushort>? _ICAP_FORCECOMPRESSION;
public CapWriter<ushort> ICAP_FORCECOMPRESSION =>
_ICAP_FORCECOMPRESSION ??= new(_twain, (CAP)KDS_CAP.ICAP_FORCECOMPRESSION, 2);
CapWriter<ushort>? _ICAP_HALFTONESQUALITY;
public CapWriter<ushort> ICAP_HALFTONESQUALITY =>
_ICAP_HALFTONESQUALITY ??= new(_twain, (CAP)KDS_CAP.ICAP_HALFTONESQUALITY, 2);
CapWriter<ushort>? _ICAP_COLORTABLE;
public CapWriter<ushort> ICAP_COLORTABLE =>
_ICAP_COLORTABLE ??= new(_twain, (CAP)KDS_CAP.ICAP_COLORTABLE, 2);
CapWriter<TW_BOOL>? _ICAP_VERTICALBLACKLINEREMOVAL;
public CapWriter<TW_BOOL> ICAP_VERTICALBLACKLINEREMOVAL =>
_ICAP_VERTICALBLACKLINEREMOVAL ??= new(_twain, (CAP)KDS_CAP.ICAP_VERTICALBLACKLINEREMOVAL, 2);
CapWriter<TW_BOOL>? _ICAP_ADDBORDER;
public CapWriter<TW_BOOL> ICAP_ADDBORDER =>
_ICAP_ADDBORDER ??= new(_twain, (CAP)KDS_CAP.ICAP_ADDBORDER, 2);
CapWriter<ushort>? _ICAP_FILTERENUM;
public CapWriter<ushort> ICAP_FILTERENUM =>
_ICAP_FILTERENUM ??= new(_twain, (CAP)KDS_CAP.ICAP_FILTERENUM, 2);
CapWriter<ushort>? _ICAP_FILTERTHRESHOLD;
public CapWriter<ushort> ICAP_FILTERTHRESHOLD =>
_ICAP_FILTERTHRESHOLD ??= new(_twain, (CAP)KDS_CAP.ICAP_FILTERTHRESHOLD, 2);
CapWriter<ushort>? _ICAP_FILTERBACKGROUND;
public CapWriter<ushort> ICAP_FILTERBACKGROUND =>
_ICAP_FILTERBACKGROUND ??= new(_twain, (CAP)KDS_CAP.ICAP_FILTERBACKGROUND, 2);
CapWriter<ushort>? _ICAP_LAMPTIMEOUT;
public CapWriter<ushort> ICAP_LAMPTIMEOUT =>
_ICAP_LAMPTIMEOUT ??= new(_twain, (CAP)KDS_CAP.ICAP_LAMPTIMEOUT, 2);
CapWriter<TW_BOOL>? _ICAP_GRAYSCALE;
public CapWriter<TW_BOOL> ICAP_GRAYSCALE =>
_ICAP_GRAYSCALE ??= new(_twain, (CAP)KDS_CAP.ICAP_GRAYSCALE, 2);
CapWriter<int>? _ICAP_COLORSHARPENING;
public CapWriter<int> ICAP_COLORSHARPENING =>
_ICAP_COLORSHARPENING ??= new(_twain, (CAP)KDS_CAP.ICAP_COLORSHARPENING, 2);
CapWriter<TW_BOOL>? _ICAP_FRAMELENGTHCONTROL;
public CapWriter<TW_BOOL> ICAP_FRAMELENGTHCONTROL =>
_ICAP_FRAMELENGTHCONTROL ??= new(_twain, (CAP)KDS_CAP.ICAP_FRAMELENGTHCONTROL, 2);
CapWriter<TW_BOOL>? _ICAP_FLIPBACKGROUNDCOLOR;
public CapWriter<TW_BOOL> ICAP_FLIPBACKGROUNDCOLOR =>
_ICAP_FLIPBACKGROUNDCOLOR ??= new(_twain, (CAP)KDS_CAP.ICAP_FLIPBACKGROUNDCOLOR, 2);
CapWriter<TW_BOOL>? _ICAP_GAMMAENABLED;
public CapWriter<TW_BOOL> ICAP_GAMMAENABLED =>
_ICAP_GAMMAENABLED ??= new(_twain, (CAP)KDS_CAP.ICAP_GAMMAENABLED, 2);
CapWriter<ushort>? _ICAP_FILTERPROCESSING;
public CapWriter<ushort> ICAP_FILTERPROCESSING =>
_ICAP_FILTERPROCESSING ??= new(_twain, (CAP)KDS_CAP.ICAP_FILTERPROCESSING, 2);
CapWriter<int>? _ICAP_AUTOCOLORAMOUNT;
public CapWriter<int> ICAP_AUTOCOLORAMOUNT =>
_ICAP_AUTOCOLORAMOUNT ??= new(_twain, (CAP)KDS_CAP.ICAP_AUTOCOLORAMOUNT, 2);
CapWriter<ushort>? _ICAP_AUTOCOLORCONTENT;
public CapWriter<ushort> ICAP_AUTOCOLORCONTENT =>
_ICAP_AUTOCOLORCONTENT ??= new(_twain, (CAP)KDS_CAP.ICAP_AUTOCOLORCONTENT, 2);
CapWriter<int>? _ICAP_AUTOCOLORTHRESHOLD;
public CapWriter<int> ICAP_AUTOCOLORTHRESHOLD =>
_ICAP_AUTOCOLORTHRESHOLD ??= new(_twain, (CAP)KDS_CAP.ICAP_AUTOCOLORTHRESHOLD, 2);
CapWriter<ushort>? _ICAP_PADDING;
public CapWriter<ushort> ICAP_PADDING =>
_ICAP_PADDING ??= new(_twain, (CAP)KDS_CAP.ICAP_PADDING, 2);
CapWriter<ushort>? _ICAP_NEWWINDOWSIZE;
public CapWriter<ushort> ICAP_NEWWINDOWSIZE =>
_ICAP_NEWWINDOWSIZE ??= new(_twain, (CAP)KDS_CAP.ICAP_NEWWINDOWSIZE, 2);
CapWriter<ushort>? _ICAP_DOCUMENTTYPE;
public CapWriter<ushort> ICAP_DOCUMENTTYPE =>
_ICAP_DOCUMENTTYPE ??= new(_twain, (CAP)KDS_CAP.ICAP_DOCUMENTTYPE, 2);
CapWriter<int>? _ICAP_SKEWANGLE;
public CapWriter<int> ICAP_SKEWANGLE =>
_ICAP_SKEWANGLE ??= new(_twain, (CAP)KDS_CAP.ICAP_SKEWANGLE, 2);
CapWriter<ushort>? _ICAP_MEDIATYPE;
public CapWriter<ushort> ICAP_MEDIATYPE =>
_ICAP_MEDIATYPE ??= new(_twain, (CAP)KDS_CAP.ICAP_MEDIATYPE, 2);
CapWriter<ushort>? _ICAP_ECDO;
public CapWriter<ushort> ICAP_ECDO =>
_ICAP_ECDO ??= new(_twain, (CAP)KDS_CAP.ICAP_ECDO, 2);
CapWriter<TW_BOOL>? _ICAP_ECDOTREATASCOLOR;
public CapWriter<TW_BOOL> ICAP_ECDOTREATASCOLOR =>
_ICAP_ECDOTREATASCOLOR ??= new(_twain, (CAP)KDS_CAP.ICAP_ECDOTREATASCOLOR, 2);
CapWriter<TW_FIX32>? _ICAP_PHYSICALHEIGHTADJUST;
public CapWriter<TW_FIX32> ICAP_PHYSICALHEIGHTADJUST =>
_ICAP_PHYSICALHEIGHTADJUST ??= new(_twain, (CAP)KDS_CAP.ICAP_PHYSICALHEIGHTADJUST, 2);
CapWriter<uint>? _ICAP_COLORSHARPEN;
public CapWriter<uint> ICAP_COLORSHARPEN =>
_ICAP_COLORSHARPEN ??= new(_twain, (CAP)KDS_CAP.ICAP_COLORSHARPEN, 2);
CapWriter<int>? _ICAP_ECDOAGGRESSIVENESS;
public CapWriter<int> ICAP_ECDOAGGRESSIVENESS =>
_ICAP_ECDOAGGRESSIVENESS ??= new(_twain, (CAP)KDS_CAP.ICAP_ECDOAGGRESSIVENESS, 2);
CapWriter<int>? _ICAP_FOREGROUNDBOLDNESSAGGRESSIVENESS;
public CapWriter<int> ICAP_FOREGROUNDBOLDNESSAGGRESSIVENESS =>
_ICAP_FOREGROUNDBOLDNESSAGGRESSIVENESS ??= new(_twain, (CAP)KDS_CAP.ICAP_FOREGROUNDBOLDNESSAGGRESSIVENESS, 2);
CapWriter<ushort>? _ICAP_FOREGROUNDBOLDNESSMODE;
public CapWriter<ushort> ICAP_FOREGROUNDBOLDNESSMODE =>
_ICAP_FOREGROUNDBOLDNESSMODE ??= new(_twain, (CAP)KDS_CAP.ICAP_FOREGROUNDBOLDNESSMODE, 2);
CapWriter<TW_BOOL>? _ICAP_TEXTENHANCEMENT;
public CapWriter<TW_BOOL> ICAP_TEXTENHANCEMENT =>
_ICAP_TEXTENHANCEMENT ??= new(_twain, (CAP)KDS_CAP.ICAP_TEXTENHANCEMENT, 2);
CapWriter<int>? _ICAP_THINTHICKENAMOUNT;
public CapWriter<int> ICAP_THINTHICKENAMOUNT =>
_ICAP_THINTHICKENAMOUNT ??= new(_twain, (CAP)KDS_CAP.ICAP_THINTHICKENAMOUNT, 2);
CapWriter<TW_BOOL>? _ICAP_ECDOINCLUDENONDROPPED;
public CapWriter<TW_BOOL> ICAP_ECDOINCLUDENONDROPPED =>
_ICAP_ECDOINCLUDENONDROPPED ??= new(_twain, (CAP)KDS_CAP.ICAP_ECDOINCLUDENONDROPPED, 2);
CapWriter<TW_BOOL>? _ICAP_AUTOCOLORIGNOREBACKGROUND;
public CapWriter<TW_BOOL> ICAP_AUTOCOLORIGNOREBACKGROUND =>
_ICAP_AUTOCOLORIGNOREBACKGROUND ??= new(_twain, (CAP)KDS_CAP.ICAP_AUTOCOLORIGNOREBACKGROUND, 2);
}

View File

@@ -50,4 +50,316 @@ public partial class KdsCaps
CapWriter<TWBK>? _CAP_BACKGROUND;
public CapWriter<TWBK> CAP_BACKGROUND =>
_CAP_BACKGROUND ??= new(_twain, (CAP)KDS_CAP.CAP_BACKGROUND, 2);
CapWriter<TWBK>? _CAP_BACKGROUNDFRONT;
public CapWriter<TWBK> CAP_BACKGROUNDFRONT =>
_CAP_BACKGROUNDFRONT ??= new(_twain, (CAP)KDS_CAP.CAP_BACKGROUNDFRONT, 2);
CapWriter<TWBK>? _CAP_BACKGROUNDREAR;
public CapWriter<TWBK> CAP_BACKGROUNDREAR =>
_CAP_BACKGROUNDREAR ??= new(_twain, (CAP)KDS_CAP.CAP_BACKGROUNDREAR, 2);
CapWriter<TWBK>? _CAP_BACKGROUNDPLATEN;
public CapWriter<TWBK> CAP_BACKGROUNDPLATEN =>
_CAP_BACKGROUNDPLATEN ??= new(_twain, (CAP)KDS_CAP.CAP_BACKGROUNDPLATEN, 2);
CapWriter<TW_FIX32>? _CAP_BATCHCOUNT;
public CapWriter<TW_FIX32> CAP_BATCHCOUNT =>
_CAP_BATCHCOUNT ??= new(_twain, (CAP)KDS_CAP.CAP_BATCHCOUNT, 2);
// TODO: verify data types below
CapWriter<TW_BOOL>? _CAP_BINARIZATION;
public CapWriter<TW_BOOL> CAP_BINARIZATION =>
_CAP_BINARIZATION ??= new(_twain, (CAP)KDS_CAP.CAP_BINARIZATION, 2);
CapWriter<TW_BOOL>? _CAP_CHECKDIGIT;
public CapWriter<TW_BOOL> CAP_CHECKDIGIT =>
_CAP_CHECKDIGIT ??= new(_twain, (CAP)KDS_CAP.CAP_CHECKDIGIT, 2);
CapWriter<TW_BOOL>? _CAP_DOUBLEFEEDENDJOB;
public CapWriter<TW_BOOL> CAP_DOUBLEFEEDENDJOB =>
_CAP_DOUBLEFEEDENDJOB ??= new(_twain, (CAP)KDS_CAP.CAP_DOUBLEFEEDENDJOB, 2);
CapWriter<TW_BOOL>? _CAP_DOUBLEFEEDSTOP;
public CapWriter<TW_BOOL> CAP_DOUBLEFEEDSTOP =>
_CAP_DOUBLEFEEDSTOP ??= new(_twain, (CAP)KDS_CAP.CAP_DOUBLEFEEDSTOP, 2);
CapWriter<TW_BOOL>? _CAP_EASYSTACKING;
public CapWriter<TW_BOOL> CAP_EASYSTACKING =>
_CAP_EASYSTACKING ??= new(_twain, (CAP)KDS_CAP.CAP_EASYSTACKING, 2);
CapWriter<TW_BOOL>? _CAP_ENABLECOLORPATCHCODE;
public CapWriter<TW_BOOL> CAP_ENABLECOLORPATCHCODE =>
_CAP_ENABLECOLORPATCHCODE ??= new(_twain, (CAP)KDS_CAP.CAP_ENABLECOLORPATCHCODE, 2);
CapWriter<int>? _CAP_ENERGYSTAR;
public CapWriter<int> CAP_ENERGYSTAR =>
_CAP_ENERGYSTAR ??= new(_twain, (CAP)KDS_CAP.CAP_ENERGYSTAR, 2);
CapWriter<TW_BOOL>? _CAP_FEEDERKEEPALIVE;
public CapWriter<TW_BOOL> CAP_FEEDERKEEPALIVE =>
_CAP_FEEDERKEEPALIVE ??= new(_twain, (CAP)KDS_CAP.CAP_FEEDERKEEPALIVE, 2);
CapWriter<ushort>? _CAP_FEEDERMODE;
public CapWriter<ushort> CAP_FEEDERMODE =>
_CAP_FEEDERMODE ??= new(_twain, (CAP)KDS_CAP.CAP_FEEDERMODE, 2);
CapWriter<TW_BOOL>? _CAP_FIXEDDOCUMENTSIZE;
public CapWriter<TW_BOOL> CAP_FIXEDDOCUMENTSIZE =>
_CAP_FIXEDDOCUMENTSIZE ??= new(_twain, (CAP)KDS_CAP.CAP_FIXEDDOCUMENTSIZE, 2);
CapWriter<ushort>? _CAP_FOLDEDCORNER;
public CapWriter<ushort> CAP_FOLDEDCORNER =>
_CAP_FOLDEDCORNER ??= new(_twain, (CAP)KDS_CAP.CAP_FOLDEDCORNER, 2);
CapWriter<ushort>? _CAP_FOLDEDCORNERSENSITIVITY;
public CapWriter<ushort> CAP_FOLDEDCORNERSENSITIVITY =>
_CAP_FOLDEDCORNERSENSITIVITY ??= new(_twain, (CAP)KDS_CAP.CAP_FOLDEDCORNERSENSITIVITY, 2);
CapWriter<TW_BOOL>? _CAP_INDICATORSWARMUP;
public CapWriter<TW_BOOL> CAP_INDICATORSWARMUP =>
_CAP_INDICATORSWARMUP ??= new(_twain, (CAP)KDS_CAP.CAP_INDICATORSWARMUP, 2);
CapWriter<int>? _CAP_MULTIFEEDCOUNT;
public CapWriter<int> CAP_MULTIFEEDCOUNT =>
_CAP_MULTIFEEDCOUNT ??= new(_twain, (CAP)KDS_CAP.CAP_MULTIFEEDCOUNT, 2);
CapWriter<ushort>? _CAP_MULTIFEEDRESPONSE;
public CapWriter<ushort> CAP_MULTIFEEDRESPONSE =>
_CAP_MULTIFEEDRESPONSE ??= new(_twain, (CAP)KDS_CAP.CAP_MULTIFEEDRESPONSE, 2);
CapWriter<TW_STR255>? _CAP_MULTIFEEDSOUND;
public CapWriter<TW_STR255> CAP_MULTIFEEDSOUND =>
_CAP_MULTIFEEDSOUND ??= new(_twain, (CAP)KDS_CAP.CAP_MULTIFEEDSOUND, 2);
CapWriter<TW_BOOL>? _CAP_MULTIFEEDTHICKNESSDETECTION;
public CapWriter<TW_BOOL> CAP_MULTIFEEDTHICKNESSDETECTION =>
_CAP_MULTIFEEDTHICKNESSDETECTION ??= new(_twain, (CAP)KDS_CAP.CAP_MULTIFEEDTHICKNESSDETECTION, 2);
CapWriter<TW_BOOL>? _CAP_NOWAIT;
public CapWriter<TW_BOOL> CAP_NOWAIT =>
_CAP_NOWAIT ??= new(_twain, (CAP)KDS_CAP.CAP_NOWAIT, 2);
CapWriter<TW_FIX32>? _CAP_PAGECOUNT;
public CapWriter<TW_FIX32> CAP_PAGECOUNT =>
_CAP_PAGECOUNT ??= new(_twain, (CAP)KDS_CAP.CAP_PAGECOUNT, 2);
CapWriter<TW_FIX32>? _CAP_PAGESIZELIMIT;
public CapWriter<TW_FIX32> CAP_PAGESIZELIMIT =>
_CAP_PAGESIZELIMIT ??= new(_twain, (CAP)KDS_CAP.CAP_PAGESIZELIMIT, 2);
CapWriter<ushort>? _CAP_PAPERDESTINATION;
public CapWriter<ushort> CAP_PAPERDESTINATION =>
_CAP_PAPERDESTINATION ??= new(_twain, (CAP)KDS_CAP.CAP_PAPERDESTINATION, 2);
CapWriter<ushort>? _CAP_PAPERJAMRESPONSE;
public CapWriter<ushort> CAP_PAPERJAMRESPONSE =>
_CAP_PAPERJAMRESPONSE ??= new(_twain, (CAP)KDS_CAP.CAP_PAPERJAMRESPONSE, 2);
CapWriter<ushort>? _CAP_PAPERSOURCE;
public CapWriter<ushort> CAP_PAPERSOURCE =>
_CAP_PAPERSOURCE ??= new(_twain, (CAP)KDS_CAP.CAP_PAPERSOURCE, 2);
CapWriter<int>? _CAP_PATCHCOUNT;
public CapWriter<int> CAP_PATCHCOUNT =>
_CAP_PATCHCOUNT ??= new(_twain, (CAP)KDS_CAP.CAP_PATCHCOUNT, 2);
CapWriter<TW_BOOL>? _CAP_PATCHHEAD1;
public CapWriter<TW_BOOL> CAP_PATCHHEAD1 =>
_CAP_PATCHHEAD1 ??= new(_twain, (CAP)KDS_CAP.CAP_PATCHHEAD1, 2);
CapWriter<TW_BOOL>? _CAP_PATCHHEAD2;
public CapWriter<TW_BOOL> CAP_PATCHHEAD2 =>
_CAP_PATCHHEAD2 ??= new(_twain, (CAP)KDS_CAP.CAP_PATCHHEAD2, 2);
CapWriter<TW_BOOL>? _CAP_PATCHHEAD3;
public CapWriter<TW_BOOL> CAP_PATCHHEAD3 =>
_CAP_PATCHHEAD3 ??= new(_twain, (CAP)KDS_CAP.CAP_PATCHHEAD3, 2);
CapWriter<TW_BOOL>? _CAP_PATCHHEAD4;
public CapWriter<TW_BOOL> CAP_PATCHHEAD4 =>
_CAP_PATCHHEAD4 ??= new(_twain, (CAP)KDS_CAP.CAP_PATCHHEAD4, 2);
CapWriter<int>? _CAP_POWEROFFTIMEOUT;
public CapWriter<int> CAP_POWEROFFTIMEOUT =>
_CAP_POWEROFFTIMEOUT ??= new(_twain, (CAP)KDS_CAP.CAP_POWEROFFTIMEOUT, 2);
CapWriter<TW_BOOL>? _CAP_POWEROFFTIMEOUTENABLED;
public CapWriter<TW_BOOL> CAP_POWEROFFTIMEOUTENABLED =>
_CAP_POWEROFFTIMEOUTENABLED ??= new(_twain, (CAP)KDS_CAP.CAP_POWEROFFTIMEOUTENABLED, 2);
CapWriter<TW_BOOL>? _CAP_ENHANCEDSEPARATION;
public CapWriter<TW_BOOL> CAP_ENHANCEDSEPARATION =>
_CAP_ENHANCEDSEPARATION ??= new(_twain, (CAP)KDS_CAP.CAP_ENHANCEDSEPARATION, 2);
CapWriter<TW_STR255>? _CAP_PRINTERDATE;
public CapWriter<TW_STR255> CAP_PRINTERDATE =>
_CAP_PRINTERDATE ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERDATE, 2);
CapWriter<ushort>? _CAP_PRINTERDATEDELIMITER;
public CapWriter<ushort> CAP_PRINTERDATEDELIMITER =>
_CAP_PRINTERDATEDELIMITER ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERDATEDELIMITER, 2);
CapWriter<ushort>? _CAP_PRINTERDATEFORMAT;
public CapWriter<ushort> CAP_PRINTERDATEFORMAT =>
_CAP_PRINTERDATEFORMAT ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERDATEFORMAT, 2);
CapWriter<ushort>? _CAP_PRINTERFONT;
public CapWriter<ushort> CAP_PRINTERFONT =>
_CAP_PRINTERFONT ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERFONT, 2);
CapWriter<ushort>? _CAP_PRINTERFONTFORMAT;
public CapWriter<ushort> CAP_PRINTERFONTFORMAT =>
_CAP_PRINTERFONTFORMAT ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERFONTFORMAT, 2);
CapWriter<int>? _CAP_PRINTERFONTRESIZE;
public CapWriter<int> CAP_PRINTERFONTRESIZE =>
_CAP_PRINTERFONTRESIZE ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERFONTRESIZE, 2);
CapWriter<TW_FIX32>? _CAP_PRINTERPOSITION;
public CapWriter<TW_FIX32> CAP_PRINTERPOSITION =>
_CAP_PRINTERPOSITION ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERPOSITION, 2);
CapWriter<TW_STR255>? _CAP_PRINTERTIME;
public CapWriter<TW_STR255> CAP_PRINTERTIME =>
_CAP_PRINTERTIME ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERTIME, 2);
CapWriter<ushort>? _CAP_PRINTERTIMEFORMAT;
public CapWriter<ushort> CAP_PRINTERTIMEFORMAT =>
_CAP_PRINTERTIMEFORMAT ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTERTIMEFORMAT, 2);
CapWriter<TW_BOOL>? _CAP_PRINTONIMAGEFRONT;
public CapWriter<TW_BOOL> CAP_PRINTONIMAGEFRONT =>
_CAP_PRINTONIMAGEFRONT ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTONIMAGEFRONT, 2);
CapWriter<TW_BOOL>? _CAP_PRINTONIMAGEREAR;
public CapWriter<TW_BOOL> CAP_PRINTONIMAGEREAR =>
_CAP_PRINTONIMAGEREAR ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTONIMAGEREAR, 2);
CapWriter<TW_FIX32>? _CAP_PRINTONIMAGEPOSITIONX;
public CapWriter<TW_FIX32> CAP_PRINTONIMAGEPOSITIONX =>
_CAP_PRINTONIMAGEPOSITIONX ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTONIMAGEPOSITIONX, 2);
CapWriter<TW_FIX32>? _CAP_PRINTONIMAGEPOSITIONY;
public CapWriter<TW_FIX32> CAP_PRINTONIMAGEPOSITIONY =>
_CAP_PRINTONIMAGEPOSITIONY ??= new(_twain, (CAP)KDS_CAP.CAP_PRINTONIMAGEPOSITIONY, 2);
CapWriter<TW_BOOL>? _CAP_SIDESDIFFERENT;
public CapWriter<TW_BOOL> CAP_SIDESDIFFERENT =>
_CAP_SIDESDIFFERENT ??= new(_twain, (CAP)KDS_CAP.CAP_SIDESDIFFERENT, 2);
CapWriter<TW_BOOL>? _CAP_SIMULATING;
public CapWriter<TW_BOOL> CAP_SIMULATING =>
_CAP_SIMULATING ??= new(_twain, (CAP)KDS_CAP.CAP_SIMULATING, 2);
CapWriter<ushort>? _CAP_TOGGLEPATCH;
public CapWriter<ushort> CAP_TOGGLEPATCH =>
_CAP_TOGGLEPATCH ??= new(_twain, (CAP)KDS_CAP.CAP_TOGGLEPATCH, 2);
CapWriter<TW_BOOL>? _CAP_TRANSPORTAUTOSTART;
public CapWriter<TW_BOOL> CAP_TRANSPORTAUTOSTART =>
_CAP_TRANSPORTAUTOSTART ??= new(_twain, (CAP)KDS_CAP.CAP_TRANSPORTAUTOSTART, 2);
CapWriter<int>? _CAP_TRANSPORTTIMEOUT;
public CapWriter<int> CAP_TRANSPORTTIMEOUT =>
_CAP_TRANSPORTTIMEOUT ??= new(_twain, (CAP)KDS_CAP.CAP_TRANSPORTTIMEOUT, 2);
CapWriter<ushort>? _CAP_TRANSPORTTIMEOUTRESPONSE;
public CapWriter<ushort> CAP_TRANSPORTTIMEOUTRESPONSE =>
_CAP_TRANSPORTTIMEOUTRESPONSE ??= new(_twain, (CAP)KDS_CAP.CAP_TRANSPORTTIMEOUTRESPONSE, 2);
CapWriter<ushort>? _CAP_ULTRASONICSENSITIVITY;
public CapWriter<ushort> CAP_ULTRASONICSENSITIVITY =>
_CAP_ULTRASONICSENSITIVITY ??= new(_twain, (CAP)KDS_CAP.CAP_ULTRASONICSENSITIVITY, 2);
CapWriter<ushort>? _CAP_ULTRASONICSENSORCENTER;
public CapWriter<ushort> CAP_ULTRASONICSENSORCENTER =>
_CAP_ULTRASONICSENSORCENTER ??= new(_twain, (CAP)KDS_CAP.CAP_ULTRASONICSENSORCENTER, 2);
CapWriter<ushort>? _CAP_ULTRASONICSENSORLEFT;
public CapWriter<ushort> CAP_ULTRASONICSENSORLEFT =>
_CAP_ULTRASONICSENSORLEFT ??= new(_twain, (CAP)KDS_CAP.CAP_ULTRASONICSENSORLEFT, 2);
CapWriter<ushort>? _CAP_ULTRASONICSENSORRIGHT;
public CapWriter<ushort> CAP_ULTRASONICSENSORRIGHT =>
_CAP_ULTRASONICSENSORRIGHT ??= new(_twain, (CAP)KDS_CAP.CAP_ULTRASONICSENSORRIGHT, 2);
CapWriter<ushort>? _CAP_ULTRASONICSENSORLEFTCENTER;
public CapWriter<ushort> CAP_ULTRASONICSENSORLEFTCENTER =>
_CAP_ULTRASONICSENSORLEFTCENTER ??= new(_twain, (CAP)KDS_CAP.CAP_ULTRASONICSENSORLEFTCENTER, 2);
CapWriter<ushort>? _CAP_ULTRASONICSENSORRIGHTCENTER;
public CapWriter<ushort> CAP_ULTRASONICSENSORRIGHTCENTER =>
_CAP_ULTRASONICSENSORRIGHTCENTER ??= new(_twain, (CAP)KDS_CAP.CAP_ULTRASONICSENSORRIGHTCENTER, 2);
CapWriter<TW_FIX32>? _CAP_ULTRASONICSENSORZONEHEIGHT;
public CapWriter<TW_FIX32> CAP_ULTRASONICSENSORZONEHEIGHT =>
_CAP_ULTRASONICSENSORZONEHEIGHT ??= new(_twain, (CAP)KDS_CAP.CAP_ULTRASONICSENSORZONEHEIGHT, 2);
CapWriter<ushort>? _CAP_WINDOWPOSITION;
public CapWriter<ushort> CAP_WINDOWPOSITION =>
_CAP_WINDOWPOSITION ??= new(_twain, (CAP)KDS_CAP.CAP_WINDOWPOSITION, 2);
}

View File

@@ -0,0 +1,66 @@
using NTwain.Data;
using System.Collections.Generic;
using System.Linq;
namespace NTwain.Caps;
public record ValueContainer<TValue> where TValue : struct
{
public TWON ContainerType { get; set; }
public TValue? OneValue { get; set; }
public IList<TValue>? ArrayValue { get; set; }
public EnumValue<TValue>? EnumValue { get; set; }
public RangeValue<TValue>? RangeValue { get; set; }
public IEnumerable<TValue> GetValues()
{
return ContainerType switch
{
TWON.ONEVALUE => OneValue.HasValue ? ToEnumerable(OneValue.Value) : [],
TWON.ARRAY => ArrayValue ?? [],
TWON.ENUMERATION => EnumValue?.Items ?? [],
TWON.RANGE => RangeValue != null ? GenerateRangeValues(RangeValue) : [],
_ => [],
};
}
private IEnumerable<TValue> ToEnumerable(TValue value)
{
yield return value;
}
private IEnumerable<TValue> GenerateRangeValues(RangeValue<TValue> range)
{
var de = new DynamicEnumerator<TValue>(range.Min, range.Max, range.Step);
while (de.MoveNext())
{
yield return de.Current;
}
}
}
public record EnumValue<TValue> where TValue : struct
{
public TValue[] Items { get; set; } = [];
public int CurrentIndex { get; set; }
public int DefaultIndex { get; set; }
}
public record RangeValue<TValue> where TValue : struct
{
public TValue Min { get; set; }
public TValue Max { get; set; }
public TValue Step { get; set; }
public TValue DefaultValue;
public TValue CurrentValue;
}

View File

@@ -0,0 +1,48 @@
using System.Collections.Generic;
namespace NTwain.Data;
// dynamic is a cheap hack to sidestep the compiler restrictions if I know TValue is numeric
class DynamicEnumerator<TValue> : IEnumerator<TValue> where TValue : struct
{
private readonly TValue _min;
private readonly TValue _max;
private readonly TValue _step;
private TValue _cur;
bool started = false;
public DynamicEnumerator(TValue min, TValue max, TValue step)
{
_min = min;
_max = max;
_step = step;
_cur = min;
}
public TValue Current => _cur;
object System.Collections.IEnumerator.Current => this.Current;
public void Dispose() { }
public bool MoveNext()
{
if (!started)
{
started = true;
return true;
}
var next = _cur + (dynamic)_step;
if (next == _cur || next < _min || next > _max) return false;
_cur = next;
return true;
}
public void Reset()
{
_cur = _min;
started = false;
}
}

View File

@@ -2590,7 +2590,9 @@ namespace NTwain.Data
ICONID = 962,
DSMID = 461,
DSMCODEID = 63
DSMCODEID = 63,
DONTCARE = 0xffff
}
///// <summary>

View File

@@ -284,58 +284,13 @@ namespace NTwain.Data
if (MinValue is not IConvertible)
throw new NotSupportedException($"The value type {typeof(TValue).Name} is not supported for range enumeration.");
return new DynamicEnumerator(MinValue, MaxValue, StepSize);
return new DynamicEnumerator<TValue>(MinValue, MaxValue, StepSize);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((IEnumerable<TValue>)this).GetEnumerator();
}
// dynamic is a cheap hack to sidestep the compiler restrictions if I know TValue is numeric
class DynamicEnumerator : IEnumerator<TValue>
{
private readonly TValue _min;
private readonly TValue _max;
private readonly TValue _step;
private TValue _cur;
bool started = false;
public DynamicEnumerator(TValue min, TValue max, TValue step)
{
_min = min;
_max = max;
_step = step;
_cur = min;
}
public TValue Current => _cur;
object System.Collections.IEnumerator.Current => this.Current;
public void Dispose() { }
public bool MoveNext()
{
if (!started)
{
started = true;
return true;
}
var next = _cur + (dynamic)_step;
if (next == _cur || next < _min || next > _max) return false;
_cur = next;
return true;
}
public void Reset()
{
_cur = _min;
started = false;
}
}
}
partial struct TW_FIX32 : IEquatable<TW_FIX32>, IConvertible

View File

@@ -1,7 +1,6 @@
using NTwain.Caps;
using NTwain.Data;
using NTwain.Triplets;
using NTwain.Triplets.ControlDATs;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -176,33 +175,49 @@ 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 IList<TValue> values) where TValue : struct
public STS GetCapValues<TValue>(CAP cap, out ValueContainer<TValue> value) where TValue : struct
{
values = new List<TValue>();
value = new ValueContainer<TValue> { ContainerType = TWON.DONTCARE };
var sts = GetCapValues(cap, out TW_CAPABILITY twcap);
if (sts.RC == TWRC.SUCCESS)
{
value.ContainerType = twcap.ConType;
switch (twcap.ConType)
{
case TWON.ONEVALUE:
values.Add(twcap.ReadOneValue<TValue>(this));
value.OneValue = twcap.ReadOneValue<TValue>(this);
break;
case TWON.ENUMERATION:
var twenum = twcap.ReadEnumeration<TValue>(this);
if (twenum.Items != null && twenum.Items.Length > 0)
((List<TValue>)values).AddRange(twenum.Items);
if (twenum.Items != null)
{
value.EnumValue = new EnumValue<TValue>
{
CurrentIndex = twenum.CurrentIndex,
DefaultIndex = twenum.DefaultIndex,
Items = twenum.Items
};
}
break;
case TWON.RANGE:
// This can be slow
var twrange = twcap.ReadRange<TValue>(this);
((List<TValue>)values).AddRange(twrange);
var range = twcap.ReadRange<TValue>(this);
value.RangeValue = new RangeValue<TValue>
{
Min = range.MinValue,
Max = range.MaxValue,
Step = range.StepSize,
DefaultValue = range.DefaultValue,
CurrentValue = range.CurrentValue
};
break;
case TWON.ARRAY:
var twarr = twcap.ReadArray<TValue>(this);
if (twarr != null && twarr.Count > 0)
((List<TValue>)values).AddRange(twarr);
if (twarr != null)
{
value.ArrayValue = twarr;
}
break;
default:
twcap.Free(this); break;