1
0
mirror of https://github.com/soukoku/ntwain.git synced 2025-04-05 20:59:23 +08:00

Added a few more easy cap value read overloads.

This commit is contained in:
Eugene Wang 2023-04-06 08:12:20 -04:00
parent f7a3cc699e
commit 9145ea1851
4 changed files with 200 additions and 40 deletions

View File

@ -39,7 +39,7 @@ namespace WinFormSample
lblCurrent.Text = ds.ProductName;
if (twain.State == STATE.S4)
{
var caps = twain.GetAllCaps();
twain.GetCapValues(CAP.CAP_SUPPORTEDCAPS, out IList<CAP> caps);
foreach (var c in caps)
listCaps.Items.Add(c);

View File

@ -9,7 +9,7 @@ namespace NTwain.Data
/// <summary>
/// Contains methods for reading pointers into various things.
/// </summary>
static class ValueReader
public static class ValueReader
{
/// <summary>
/// Reads pointer as UTF8 string.

View File

@ -11,20 +11,20 @@ namespace NTwain
partial class TwainAppSession
{
/// <summary>
/// Gets all the supported caps for the current source.
/// </summary>
/// <returns></returns>
public IList<CAP> GetAllCaps()
{
// just as a sample of how to read cap values
///// <summary>
///// Gets all the supported caps for the current source.
///// </summary>
///// <returns></returns>
//public IList<CAP> GetAllCaps()
//{
// // just as a sample of how to read cap values
if (GetCapValues(CAP.CAP_SUPPORTEDCAPS, out TW_CAPABILITY value).RC == TWRC.SUCCESS)
{
return value.ReadArray<CAP>(this);
}
return Array.Empty<CAP>();
}
// if (GetCapValues(CAP.CAP_SUPPORTEDCAPS, out TW_CAPABILITY value).RC == TWRC.SUCCESS)
// {
// return value.ReadArray<CAP>(this);
// }
// return Array.Empty<CAP>();
//}
/// <summary>
/// Gets a CAP's actual supported operations.
@ -43,8 +43,8 @@ namespace NTwain
}
/// <summary>
/// Gets a CAP's current value.
/// Caller will need to free the memory.
/// Gets a CAP's raw current value.
/// Caller will need to manually read and free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
@ -56,8 +56,49 @@ namespace NTwain
}
/// <summary>
/// Gets a CAP's default value.
/// Caller will need to free the memory.
/// Gets a CAP's current value. This is a simplified version that doesn't require
/// manual reading, but may or may not work.
/// </summary>
/// <typeparam name="TValue"></typeparam>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapCurrent<TValue>(CAP cap, out TValue value) where TValue : struct
{
value = default;
var sts = GetCapCurrent(cap, out TW_CAPABILITY twcap);
if (sts.RC == TWRC.SUCCESS)
{
switch (twcap.ConType)
{
case TWON.ONEVALUE:
value = twcap.ReadOneValue<TValue>(this);
break;
case TWON.ENUMERATION:
var twenum = twcap.ReadEnumeration<TValue>(this);
if (twenum.Items != null && twenum.CurrentIndex < twenum.Items.Length)
{
value = twenum.Items[twenum.CurrentIndex];
}
break;
case TWON.RANGE:
value = twcap.ReadRange<TValue>(this).CurrentValue;
break;
case TWON.ARRAY:
// no source should ever return an array but anyway
var twarr = twcap.ReadArray<TValue>(this);
if (twarr != null && twarr.Count > 0) value = twarr[0];
break;
default:
twcap.Free(this); break;
}
}
return sts;
}
/// <summary>
/// Gets a CAP's raw default value.
/// Caller will need to manually read and free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
@ -68,9 +109,51 @@ namespace NTwain
return WrapInSTS(DGControl.Capability.GetDefault(ref _appIdentity, ref _currentDS, ref value));
}
/// <summary>
/// Gets a CAP's supported values.
/// Caller will need to free the memory.
/// Gets a CAP's default value. This is a simplified version that doesn't require
/// manual reading, but may or may not work.
/// </summary>
/// <typeparam name="TValue"></typeparam>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapDefault<TValue>(CAP cap, out TValue value) where TValue : struct
{
value = default;
var sts = GetCapDefault(cap, out TW_CAPABILITY twcap);
if (sts.RC == TWRC.SUCCESS)
{
switch (twcap.ConType)
{
case TWON.ONEVALUE:
value = twcap.ReadOneValue<TValue>(this);
break;
case TWON.ENUMERATION:
var twenum = twcap.ReadEnumeration<TValue>(this);
if (twenum.Items != null && twenum.DefaultIndex < twenum.Items.Length)
{
value = twenum.Items[twenum.DefaultIndex];
}
break;
case TWON.RANGE:
value = twcap.ReadRange<TValue>(this).DefaultValue;
break;
case TWON.ARRAY:
// no source should ever return an array but anyway
var twarr = twcap.ReadArray<TValue>(this);
if (twarr != null && twarr.Count > 0) value = twarr[0];
break;
default:
twcap.Free(this); break;
}
}
return sts;
}
/// <summary>
/// Gets a CAP's raw supported values.
/// Caller will need to manually read and free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
@ -81,9 +164,51 @@ namespace NTwain
return WrapInSTS(DGControl.Capability.Get(ref _appIdentity, ref _currentDS, ref value));
}
/// <summary>
/// Gets a CAP's supported values. This is a simplified version that doesn't require
/// manual reading, but may or may not work.
/// </summary>
/// <typeparam name="TValue"></typeparam>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS GetCapValues<TValue>(CAP cap, out IList<TValue> values) where TValue : struct
{
values = new List<TValue>();
var sts = GetCapCurrent(cap, out TW_CAPABILITY twcap);
if (sts.RC == TWRC.SUCCESS)
{
switch (twcap.ConType)
{
case TWON.ONEVALUE:
values.Add(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);
break;
case TWON.RANGE:
// This can be slow
var twrange = twcap.ReadRange<TValue>(this);
((List<TValue>)values).AddRange(twrange);
break;
case TWON.ARRAY:
var twarr = twcap.ReadArray<TValue>(this);
if (twarr != null && twarr.Count > 0)
((List<TValue>)values).AddRange(twarr);
break;
default:
twcap.Free(this); break;
}
}
return sts;
}
/// <summary>
/// Gets a CAP's help text (description).
/// This is not implemented.
/// This is not implemented due to unclear spec.
/// </summary>
/// <param name="cap"></param>
/// <param name="help"></param>
@ -95,7 +220,7 @@ namespace NTwain
var rc = DGControl.Capability.GetHelp(ref _appIdentity, ref _currentDS, ref value);
if (rc == TWRC.SUCCESS)
{
// how to determine the length of this thing???
// TODO: how to determine the length of this thing???
var data = value.ReadOneValue<IntPtr>(this, false);
}
value.Free(this);
@ -104,7 +229,7 @@ namespace NTwain
/// <summary>
/// Gets a CAP's text name label.
/// This is not implemented.
/// This is not implemented due to unclear spec.
/// </summary>
/// <param name="cap"></param>
/// <param name="label"></param>
@ -116,7 +241,7 @@ namespace NTwain
var rc = DGControl.Capability.GetLabel(ref _appIdentity, ref _currentDS, ref value);
if (rc == TWRC.SUCCESS)
{
// how to determine the length of this thing???
// TODO: how to determine the length of this thing???
var data = value.ReadOneValue<IntPtr>(this, false);
}
value.Free(this);
@ -124,7 +249,7 @@ namespace NTwain
}
/// <summary>
/// Gets a CAP's value label texts.
/// Gets a CAP's enum/array value label texts.
/// </summary>
/// <param name="cap"></param>
/// <param name="labels"></param>
@ -145,6 +270,7 @@ namespace NTwain
/// <summary>
/// Sets a CAP's current value.
/// Memory of the value will be freed afterwards.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
@ -163,6 +289,7 @@ namespace NTwain
/// <summary>
/// Sets a CAP's constraint values.
/// Memory of the value will be freed afterwards.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
@ -175,7 +302,7 @@ namespace NTwain
/// <summary>
/// Resets a CAP's current value to power-on default.
/// Caller will need to free the memory.
/// Caller will need to manually read and free the memory.
/// </summary>
/// <param name="cap"></param>
/// <param name="value"></param>
@ -193,12 +320,52 @@ namespace NTwain
return WrapInSTS(rc);
}
/// <summary>
/// Resets a CAP's current value to power-on default.
/// </summary>
/// <typeparam name="TValue"></typeparam>
/// <param name="cap"></param>
/// <param name="value"></param>
/// <returns></returns>
public STS ResetCap<TValue>(CAP cap, out TValue value) where TValue : struct
{
value = default;
var sts = ResetCap(cap, out TW_CAPABILITY twcap);
if (sts.RC == TWRC.SUCCESS)
{
switch (twcap.ConType)
{
case TWON.ONEVALUE:
value = twcap.ReadOneValue<TValue>(this);
break;
case TWON.ENUMERATION:
var twenum = twcap.ReadEnumeration<TValue>(this);
if (twenum.Items != null && twenum.CurrentIndex < twenum.Items.Length)
{
value = twenum.Items[twenum.CurrentIndex];
}
break;
case TWON.RANGE:
value = twcap.ReadRange<TValue>(this).CurrentValue;
break;
case TWON.ARRAY:
var twarr = twcap.ReadArray<TValue>(this);
if (twarr != null && twarr.Count > 0) value = twarr[0];
break;
default:
twcap.Free(this); break;
}
}
return sts;
}
/// <summary>
/// Resets all CAP values and constraint to power-on defaults.
/// </summary>
/// <returns></returns>
public STS ResetAllCaps()
{
// no memory is allocated for this
var value = new TW_CAPABILITY(CAP.CAP_SUPPORTEDCAPS);
var rc = DGControl.Capability.ResetAll(ref _appIdentity, ref _currentDS, ref value);
@ -212,10 +379,9 @@ namespace NTwain
private void RefreshCapLanguage()
{
var rc2 = GetCapCurrent(CAP.CAP_LANGUAGE, out TW_CAPABILITY curCap);
var rc2 = GetCapCurrent(CAP.CAP_LANGUAGE, out TWLG lang);
if (rc2.RC == TWRC.SUCCESS)
{
var lang = curCap.ReadOneValue<TWLG>(this);
Language.Set(lang);
}
}

View File

@ -16,7 +16,7 @@ namespace NTwain
// experiment using array pool for things transferred in memory.
// this can pool up to a "normal" max of legal size paper in 24 bit at 300 dpi (~31MB)
// so the array max is made with 32 MB. Typical usage should be a lot less.
static readonly ArrayPool<byte> XferMemPool = ArrayPool<byte>.Create(32505856, 4);
static readonly ArrayPool<byte> XferMemPool = ArrayPool<byte>.Create(32 * 1024 * 1024, 8);
public STS GetImageInfo(out TW_IMAGEINFO info)
{
@ -34,8 +34,6 @@ namespace NTwain
// default options if source doesn't support changing them or whatever
bool xferImage = true;
bool xferAudio = false;
var imgXferMech = TWSX.NATIVE;
var audXferMech = TWSX.NATIVE;
if (DGControl.XferGroup.Get(ref _appIdentity, ref _currentDS, out DG xferType) == TWRC.SUCCESS)
{
xferAudio = (xferType & DG.AUDIO) == DG.AUDIO;
@ -54,14 +52,10 @@ namespace NTwain
}
}
if (xferImage && GetCapCurrent(CAP.ICAP_XFERMECH, out TW_CAPABILITY cap).RC == TWRC.SUCCESS)
{
imgXferMech = cap.ReadOneValue<TWSX>(this);
}
else if (xferAudio && GetCapCurrent(CAP.ACAP_XFERMECH, out cap).RC == TWRC.SUCCESS)
{
audXferMech = cap.ReadOneValue<TWSX>(this);
}
var imgXferMech = TWSX.NATIVE;
var audXferMech = TWSX.NATIVE;
if (xferImage) GetCapCurrent(CAP.ICAP_XFERMECH, out imgXferMech);
else if (xferAudio) GetCapCurrent(CAP.ACAP_XFERMECH, out audXferMech);
TW_PENDINGXFERS pending = default;
var rc = DGControl.PendingXfers.Get(ref _appIdentity, ref _currentDS, ref pending);