Added GetLabel/GetHelp for caps as experiment.

This commit is contained in:
Eugene Wang
2021-04-25 14:43:15 -04:00
parent 8fe54398b9
commit 65a07e0254
4 changed files with 193 additions and 27 deletions

View File

@@ -76,10 +76,10 @@ namespace Net5Console
var caps = session.Capabilities; var caps = session.Capabilities;
Console.WriteLine("Device supports these caps:"); Console.WriteLine("Device supports these caps:");
//foreach (var cap in caps.Keys.OrderBy(c => c)) foreach (var cap in caps.CAP_SUPPORTEDCAPS.GetValues())
//{ {
// Console.WriteLine($"\t{cap}: {caps[cap].Supports}"); WriteCapInfo(caps, cap);
//} }
Console.WriteLine(); Console.WriteLine();
//if (caps.TryGetValue(CAP.ICAP_PIXELTYPE, out CapWrapper wrapper)) //if (caps.TryGetValue(CAP.ICAP_PIXELTYPE, out CapWrapper wrapper))
@@ -123,5 +123,18 @@ namespace Net5Console
} }
} }
private static void WriteCapInfo(Capabilities caps, CAP cap)
{
// use reflection due to generics
var propInfo = typeof(Capabilities).GetProperty(cap.ToString());
if (propInfo == null) return;
var capWrapper = propInfo.GetValue(caps);
var label = (string)capWrapper.GetType().GetMethod(nameof(CapWrapper<int>.GetLabel)).Invoke(capWrapper, null);
var supports = (TWQC)capWrapper.GetType().GetMethod(nameof(CapWrapper<int>.QuerySupport)).Invoke(capWrapper, null);
Console.WriteLine($"\t{label ?? cap.ToString()}: {supports}");
}
} }
} }

View File

@@ -17,31 +17,32 @@ namespace NTwain
{ {
_twain = twain; _twain = twain;
Cap = cap; Cap = cap;
var twCap = new TW_CAPABILITY
{
Cap = cap
};
var sts = _twain.DatCapability(DG.CONTROL, MSG.QUERYSUPPORT, ref twCap);
if (sts == STS.SUCCESS && twCap.ConType == TWON.ONEVALUE)
{
Supports = ValueReader.ReadOneValue<TWQC>(_twain, twCap);
} }
}
/// <summary>
/// The operations supported by the cap.
/// Not all sources supports this so it may be unknown.
/// </summary>
public TWQC Supports { get; }
/// <summary> /// <summary>
/// The cap being targeted. /// The cap being targeted.
/// </summary> /// </summary>
public CAP Cap { get; } public CAP Cap { get; }
/// <summary>
/// Gets the operations supported by the cap.
/// Not all sources supports this so it may be unknown.
/// </summary>
public TWQC QuerySupport()
{
var twCap = new TW_CAPABILITY
{
Cap = Cap
};
var sts = _twain.DatCapability(DG.CONTROL, MSG.QUERYSUPPORT, ref twCap);
if (sts == STS.SUCCESS && twCap.ConType == TWON.ONEVALUE)
{
return ValueReader.ReadOneValue<TWQC>(_twain, twCap);
}
return TWQC.Uknown;
}
/// <summary> /// <summary>
/// Try to get list of the cap's supported values. /// Try to get list of the cap's supported values.
/// </summary> /// </summary>
@@ -125,6 +126,44 @@ namespace NTwain
return default(TValue); return default(TValue);
} }
/// <summary>
/// Try to get the cap's label text.
/// </summary>
/// <returns></returns>
public string GetLabel()
{
var twCap = new TW_CAPABILITY
{
Cap = Cap
};
var sts = _twain.DatCapability(DG.CONTROL, MSG.GETLABEL, ref twCap);
if (sts == STS.SUCCESS)
{
return ValueReader.ReadOneString(_twain, twCap);
}
return null;
}
/// <summary>
/// Try to get the cap's description text.
/// </summary>
/// <returns></returns>
public string GetHelp()
{
var twCap = new TW_CAPABILITY
{
Cap = Cap
};
var sts = _twain.DatCapability(DG.CONTROL, MSG.GETHELP, ref twCap);
if (sts == STS.SUCCESS)
{
return ValueReader.ReadOneString(_twain, twCap);
}
return null;
}
/// <summary> /// <summary>
/// Resets the cap's current value to power-on default. /// Resets the cap's current value to power-on default.
/// </summary> /// </summary>

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@@ -13,7 +14,7 @@ namespace NTwain
/// </summary> /// </summary>
public static class ValueReader public static class ValueReader
{ {
public static TValue ReadOneValue<TValue>(TWAIN twain, TW_CAPABILITY cap) where TValue : struct public static TValue ReadOneValue<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{ {
if (cap.hContainer == IntPtr.Zero) return default(TValue); if (cap.hContainer == IntPtr.Zero) return default(TValue);
@@ -43,21 +44,134 @@ namespace NTwain
finally finally
{ {
twain.DsmMemUnlock(cap.hContainer); twain.DsmMemUnlock(cap.hContainer);
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
} }
} }
public static IList<TValue> ReadEnumeration<TValue>(TWAIN twain, TW_CAPABILITY twCap) where TValue : struct public static IList<TValue> ReadEnumeration<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public static IList<TValue> ReadArray<TValue>(TWAIN twain, TW_CAPABILITY twCap) where TValue : struct public static IList<TValue> ReadArray<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{ {
throw new NotImplementedException(); var list = new List<TValue>();
if (cap.hContainer == IntPtr.Zero) return list;
var lockedPtr = twain.DsmMemLock(cap.hContainer);
try
{
TWTY itemType;
uint count;
// Mac has a level of indirection and a different structure (ick)...
if (PlatformTools.GetPlatform() == Platform.MACOSX)
{
// Crack the container...
TW_ARRAY_MACOSX twarraymacosx = default(TW_ARRAY_MACOSX);
twarraymacosx = MarshalTo<TW_ARRAY_MACOSX>(lockedPtr);
itemType = (TWTY)twarraymacosx.ItemType;
count = twarraymacosx.NumItems;
lockedPtr += Marshal.SizeOf(twarraymacosx);
} }
public static (TValue defaultVal, TValue currentVal, IEnumerable<TValue> values) ReadRange<TValue>(TWAIN twain, TW_CAPABILITY twCap) where TValue : struct else
{
// Crack the container...
TW_ARRAY twarray = default(TW_ARRAY);
twarray = MarshalTo<TW_ARRAY>(lockedPtr);
itemType = twarray.ItemType;
count = twarray.NumItems;
lockedPtr += Marshal.SizeOf(twarray);
}
for (var i = 0; i < count; i++)
{
list.Add(ReadContainerData<TValue>(lockedPtr, itemType, i));
}
}
finally
{
twain.DsmMemUnlock(cap.hContainer);
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
}
return list;
}
public static (TValue defaultVal, TValue currentVal, IEnumerable<TValue> values)
ReadRange<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>
/// Read the one value of a cap as string. Only STR* and HANDLE types are supported.
/// </summary>
/// <param name="twain"></param>
/// <param name="cap"></param>
/// <param name="freeMemory"></param>
/// <returns></returns>
public static string ReadOneString(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true)
{
if (cap.hContainer == IntPtr.Zero) return null;
var lockedPtr = twain.DsmMemLock(cap.hContainer);
try
{
if (cap.ConType == TWON.ONEVALUE)
{
TWTY itemType;
// Mac has a level of indirection and a different structure (ick)...
if (PlatformTools.GetPlatform() == Platform.MACOSX)
{
// Crack the container...
var onevalue = MarshalTo<TW_ONEVALUE_MACOSX>(lockedPtr);
itemType = (TWTY)onevalue.ItemType;
lockedPtr += Marshal.SizeOf(onevalue);
}
else
{
// Crack the container...
var onevalue = MarshalTo<TW_ONEVALUE>(lockedPtr);
itemType = onevalue.ItemType;
lockedPtr += Marshal.SizeOf(onevalue);
}
switch (itemType)
{
case TWTY.STR32:
return MarshalTo<TW_STR32>(lockedPtr).ToString();
case TWTY.STR64:
return MarshalTo<TW_STR64>(lockedPtr).ToString();
case TWTY.STR128:
return MarshalTo<TW_STR128>(lockedPtr).ToString();
case TWTY.STR255:
return MarshalTo<TW_STR255>(lockedPtr).ToString();
case TWTY.HANDLE:
// null-terminated and encoded string.
// good chance this ain't right.
using (var stream = new MemoryStream())
{
byte read = Marshal.ReadByte(lockedPtr);
while (read != 0)
{
stream.WriteByte(read);
read = Marshal.ReadByte(lockedPtr);
lockedPtr += 1;
}
// which one?
return Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, stream.ToArray()));
//return Language.GetEncoding().GetString(stream.ToArray());
}
}
}
}
finally
{
twain.DsmMemUnlock(cap.hContainer);
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
}
return null;
}
/// <summary> /// <summary>
/// Read the container pointer content. /// Read the container pointer content.
/// </summary> /// </summary>