mirror of
https://github.com/soukoku/ntwain.git
synced 2026-01-26 13:39:47 +08:00
Added GetLabel/GetHelp for caps as experiment.
This commit is contained in:
@@ -76,10 +76,10 @@ namespace Net5Console
|
||||
|
||||
var caps = session.Capabilities;
|
||||
Console.WriteLine("Device supports these caps:");
|
||||
//foreach (var cap in caps.Keys.OrderBy(c => c))
|
||||
//{
|
||||
// Console.WriteLine($"\t{cap}: {caps[cap].Supports}");
|
||||
//}
|
||||
foreach (var cap in caps.CAP_SUPPORTEDCAPS.GetValues())
|
||||
{
|
||||
WriteCapInfo(caps, cap);
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
//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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,31 +17,32 @@ namespace NTwain
|
||||
{
|
||||
_twain = twain;
|
||||
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>
|
||||
/// The cap being targeted.
|
||||
/// </summary>
|
||||
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>
|
||||
/// Try to get list of the cap's supported values.
|
||||
/// </summary>
|
||||
@@ -125,6 +126,44 @@ namespace NTwain
|
||||
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>
|
||||
/// Resets the cap's current value to power-on default.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
@@ -13,7 +14,7 @@ namespace NTwain
|
||||
/// </summary>
|
||||
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);
|
||||
|
||||
@@ -43,21 +44,134 @@ namespace NTwain
|
||||
finally
|
||||
{
|
||||
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();
|
||||
}
|
||||
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);
|
||||
}
|
||||
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 twCap) where TValue : struct
|
||||
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();
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Read the container pointer content.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user