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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,101 +4,97 @@ using System.Collections.Generic;
namespace NTwain.Caps 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> /// <summary>
/// When this was introduced in TWAIN. ///
/// </summary> /// </summary>
public float Introduced { get; } /// <typeparam name="TValue"></typeparam>
public class CapReader<TValue> where TValue : struct
/// <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
{ {
get protected readonly TwainAppSession _twain;
{
if (!_qc.HasValue) _qc = _twain.QueryCapSupport(Cap);
return _qc.Value;
}
}
public IList<TValue> Get() public CapReader(TwainAppSession twain, CAP cap, float introducedVersion = 1)
{ {
LastSTS = _twain.GetCapValues(Cap, out IList<TValue> values); _twain = twain;
if (LastSTS.IsSuccess) Cap = cap;
{ Introduced = introducedVersion;
return values; }
};
return Array.Empty<TValue>();
}
public IList<TValue> GetCurrent() public CAP Cap { get; }
{
LastSTS = _twain.GetCapCurrent(Cap, out List<TValue> value);
if (LastSTS.IsSuccess)
{
return value;
};
return Array.Empty<TValue>();
}
public IList<TValue> GetDefault() /// <summary>
{ /// When this was introduced in TWAIN.
LastSTS = _twain.GetCapDefault(Cap, out List<TValue> value); /// </summary>
if (LastSTS.IsSuccess) public float Introduced { get; }
{
return value;
};
return Array.Empty<TValue>();
}
public string? GetLabel() /// <summary>
{ /// The STS result from the most recent call with this cap wrapper.
LastSTS = _twain.GetCapLabel(Cap, out string? value); /// </summary>
if (LastSTS.IsSuccess) public STS LastSTS { get; protected set; }
{
return value;
};
return default;
}
public string? GetHelp() TWQC? _qc;
{ public TWQC Supports
LastSTS = _twain.GetCapHelp(Cap, out string? value); {
if (LastSTS.IsSuccess) get
{ {
return value; if (!_qc.HasValue) _qc = _twain.QueryCapSupport(Cap);
}; return _qc.Value;
return default; }
} }
public IList<string> GetLabelEnum() public ValueContainer<TValue> Get()
{ {
LastSTS = _twain.GetCapLabelEnum(Cap, out IList<string> value); LastSTS = _twain.GetCapValues(Cap, out ValueContainer<TValue> value);
if (LastSTS.IsSuccess) return value;
{ }
return value;
}; public IList<TValue> GetCurrent()
return Array.Empty<string>(); {
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 => public CapWriter<TWCBR> ICAP_COLORBRIGHTNESSMODE =>
_ICAP_COLORBRIGHTNESSMODE ??= new(_twain, (CAP)KDS_CAP.ICAP_COLORBRIGHTNESSMODE, 2); _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; CapWriter<TWBK>? _CAP_BACKGROUND;
public CapWriter<TWBK> CAP_BACKGROUND => public CapWriter<TWBK> CAP_BACKGROUND =>
_CAP_BACKGROUND ??= new(_twain, (CAP)KDS_CAP.CAP_BACKGROUND, 2); _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, ICONID = 962,
DSMID = 461, DSMID = 461,
DSMCODEID = 63 DSMCODEID = 63,
DONTCARE = 0xffff
} }
///// <summary> ///// <summary>

View File

@@ -284,58 +284,13 @@ namespace NTwain.Data
if (MinValue is not IConvertible) if (MinValue is not IConvertible)
throw new NotSupportedException($"The value type {typeof(TValue).Name} is not supported for range enumeration."); 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() System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{ {
return ((IEnumerable<TValue>)this).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 partial struct TW_FIX32 : IEquatable<TW_FIX32>, IConvertible

View File

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