mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
Updated string read and fixed sample.
This commit is contained in:
parent
9d30efe92a
commit
f861cd8c60
NTwain
Data
DataTransferredEventArgs.csNTwain.nuspecTransferReadyEventArgs.csTriplets
TwainSession.csTwainSessionOld.csTests
NTwain.Tests
Tester.Console
Tester.WPF
Tester.Winform
@ -266,16 +266,16 @@ namespace NTwain.Data
|
||||
frame.Bottom = (TWFix32)ReadValue(baseAddr, ref offset, ItemType.Fix32);
|
||||
return frame; // no need to update offset again after reading fix32
|
||||
case ItemType.String128:
|
||||
val = ReadString(baseAddr, offset, 128);
|
||||
val = ReadString(baseAddr, offset, TwainConst.String128 - 2);
|
||||
break;
|
||||
case ItemType.String255:
|
||||
val = ReadString(baseAddr, offset, 255);
|
||||
val = ReadString(baseAddr, offset, TwainConst.String255 - 1);
|
||||
break;
|
||||
case ItemType.String32:
|
||||
val = ReadString(baseAddr, offset, 32);
|
||||
val = ReadString(baseAddr, offset, TwainConst.String32 - 2);
|
||||
break;
|
||||
case ItemType.String64:
|
||||
val = ReadString(baseAddr, offset, 64);
|
||||
val = ReadString(baseAddr, offset, TwainConst.String64 - 2);
|
||||
break;
|
||||
case ItemType.Handle:
|
||||
val = new IntPtr(baseAddr.ToInt64() + offset);
|
||||
@ -294,16 +294,21 @@ namespace NTwain.Data
|
||||
/// <returns></returns>
|
||||
static string ReadString(IntPtr baseAddr, int offset, int maxLength)
|
||||
{
|
||||
// todo: add support for other platform
|
||||
|
||||
var sb = new StringBuilder(maxLength);
|
||||
byte bt;
|
||||
while (sb.Length < maxLength &&
|
||||
(bt = Marshal.ReadByte(baseAddr, offset++)) != 0)
|
||||
// does this work cross-platform?
|
||||
var val = Marshal.PtrToStringAnsi(new IntPtr(baseAddr.ToInt64() + offset));
|
||||
if (val.Length > maxLength)
|
||||
{
|
||||
sb.Append((char)bt);
|
||||
// bad source, whatever
|
||||
}
|
||||
return sb.ToString();
|
||||
return val;
|
||||
//var sb = new StringBuilder(maxLength);
|
||||
//byte bt;
|
||||
//while (sb.Length < maxLength &&
|
||||
// (bt = Marshal.ReadByte(baseAddr, offset++)) != 0)
|
||||
//{
|
||||
// sb.Append((char)bt);
|
||||
//}
|
||||
//return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using NTwain.Data;
|
||||
using System;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
@ -8,30 +9,36 @@ namespace NTwain
|
||||
public class DataTransferredEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTransferredEventArgs" /> class.
|
||||
/// </summary>
|
||||
/// <param name="data">The data pointer.</param>
|
||||
/// <param name="filePath">The file.</param>
|
||||
internal DataTransferredEventArgs(IntPtr data, string filePath)
|
||||
{
|
||||
Data = data;
|
||||
FilePath = filePath;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets pointer to the image data if applicable.
|
||||
/// Gets pointer to the complete data if the transfer was native.
|
||||
/// The data will be freed once the event handler ends
|
||||
/// so consumers must complete whatever processing
|
||||
/// required by then.
|
||||
/// so consumers must complete whatever processing before then.
|
||||
/// For image type this data is DIB (Windows), PICT (old Mac), and TIFF (Linux/OSX).
|
||||
/// </summary>
|
||||
/// <value>The data pointer.</value>
|
||||
public IntPtr Data { get; private set; }
|
||||
public IntPtr NativeData { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filepath to the transferrerd data if applicable.
|
||||
/// Gets the file path to the complete data if the transfer was file or memory-file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The file.
|
||||
/// </value>
|
||||
public string FilePath { get; private set; }
|
||||
public string FilePath { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the memory data if the transfer was memory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The memory data.
|
||||
/// </value>
|
||||
public byte[] MemData { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the final image information if applicable.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The final image information.
|
||||
/// </value>
|
||||
public TWImageInfo FinalImageInfo { get; internal set; }
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
<!--<iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>-->
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>$description$</description>
|
||||
<releaseNotes>V0.9 release is updated for TWAIN 2.3 and contains some refactoring that may require updating existing code.</releaseNotes>
|
||||
<releaseNotes>This release supports TWAIN 2.3.</releaseNotes>
|
||||
<copyright>$copyright$</copyright>
|
||||
<tags>twain scan</tags>
|
||||
</metadata>
|
||||
|
@ -39,7 +39,7 @@ namespace NTwain
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tentative image information for the current transfer if applicable.
|
||||
/// This may differ from the final image depending on the transfer mode used.
|
||||
/// This may differ from the final image depending on the transfer mode used (mostly when doing mem xfer).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The image info.
|
||||
|
@ -11,10 +11,11 @@ namespace NTwain.Triplets
|
||||
{
|
||||
internal ExtImageInfo(ITwainStateInternal session) : base(session) { }
|
||||
|
||||
public ReturnCode Get(TWExtImageInfo info)
|
||||
public ReturnCode Get(out TWExtImageInfo info)
|
||||
{
|
||||
Session.VerifyState(7, 7, DataGroups.Image, DataArgumentType.ExtImageInfo, Message.Get);
|
||||
return PInvoke.DsmEntry(Session.GetAppId(), Session.SourceId, Message.Get, info);
|
||||
info = new TWExtImageInfo();
|
||||
return PInvoke.DsmEntry(Session.GetAppId(), Session.SourceId, Message.Get, info);
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,10 @@ namespace NTwain.Triplets
|
||||
File.Exists(path);
|
||||
}
|
||||
|
||||
static readonly bool IsWin = Environment.OSVersion.Platform == PlatformID.Win32NT;
|
||||
static readonly bool IsOSX = Environment.OSVersion.Platform == PlatformID.MacOSX;
|
||||
static readonly bool IsLinux = Environment.OSVersion.Platform == PlatformID.Unix;
|
||||
|
||||
// define sig for each different data type since "object" doesn't work
|
||||
|
||||
#region wrapped calls
|
||||
|
@ -37,6 +37,7 @@ namespace NTwain
|
||||
object _callbackObj; // kept around so it doesn't get gc'ed
|
||||
TWUserInterface _twui;
|
||||
|
||||
static readonly CapabilityId[] _emptyCapList = new CapabilityId[0];
|
||||
|
||||
private IList<CapabilityId> _supportedCaps;
|
||||
/// <summary>
|
||||
@ -53,7 +54,7 @@ namespace NTwain
|
||||
{
|
||||
_supportedCaps = this.GetCapabilities();
|
||||
}
|
||||
return _supportedCaps ?? new CapabilityId[0];
|
||||
return _supportedCaps ?? _emptyCapList;
|
||||
}
|
||||
private set
|
||||
{
|
||||
@ -289,6 +290,7 @@ namespace NTwain
|
||||
if (rc == ReturnCode.Success)
|
||||
{
|
||||
_callbackObj = null;
|
||||
SupportedCaps = null;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -776,7 +778,7 @@ namespace NTwain
|
||||
{
|
||||
lockedPtr = MemoryManager.Instance.Lock(dataPtr);
|
||||
}
|
||||
OnDataTransferred(new DataTransferredEventArgs(lockedPtr, null));
|
||||
OnDataTransferred(new DataTransferredEventArgs { NativeData = lockedPtr });
|
||||
}
|
||||
}
|
||||
finally
|
||||
@ -808,7 +810,7 @@ namespace NTwain
|
||||
var xrc = DGAudio.AudioFileXfer.Get();
|
||||
if (xrc == ReturnCode.XferDone)
|
||||
{
|
||||
OnDataTransferred(new DataTransferredEventArgs(IntPtr.Zero, filePath));
|
||||
OnDataTransferred(new DataTransferredEventArgs { FilePath = filePath });
|
||||
}
|
||||
}
|
||||
|
||||
@ -826,11 +828,16 @@ namespace NTwain
|
||||
if (xrc == ReturnCode.XferDone)
|
||||
{
|
||||
State = 7;
|
||||
TWImageInfo imgInfo;
|
||||
if (DGImage.ImageInfo.Get(out imgInfo) != ReturnCode.Success)
|
||||
{
|
||||
imgInfo = null;
|
||||
}
|
||||
if (dataPtr != IntPtr.Zero)
|
||||
{
|
||||
lockedPtr = MemoryManager.Instance.Lock(dataPtr);
|
||||
}
|
||||
OnDataTransferred(new DataTransferredEventArgs(lockedPtr, null));
|
||||
OnDataTransferred(new DataTransferredEventArgs { NativeData = lockedPtr, FinalImageInfo = imgInfo });
|
||||
}
|
||||
}
|
||||
finally
|
||||
@ -862,13 +869,93 @@ namespace NTwain
|
||||
var xrc = DGImage.ImageFileXfer.Get();
|
||||
if (xrc == ReturnCode.XferDone)
|
||||
{
|
||||
OnDataTransferred(new DataTransferredEventArgs(IntPtr.Zero, filePath));
|
||||
TWImageInfo imgInfo;
|
||||
if (DGImage.ImageInfo.Get(out imgInfo) != ReturnCode.Success)
|
||||
{
|
||||
imgInfo = null;
|
||||
}
|
||||
OnDataTransferred(new DataTransferredEventArgs { FilePath = filePath, FinalImageInfo = imgInfo });
|
||||
}
|
||||
}
|
||||
|
||||
private void DoImageMemoryXfer()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
TWSetupMemXfer memInfo;
|
||||
if (DGControl.SetupMemXfer.Get(out memInfo) == ReturnCode.Success)
|
||||
{
|
||||
TWImageMemXfer xferInfo = new TWImageMemXfer();
|
||||
try
|
||||
{
|
||||
xferInfo.Memory = new TWMemory
|
||||
{
|
||||
Flags = MemoryFlags.AppOwns | MemoryFlags.Pointer,
|
||||
Length = memInfo.Preferred,
|
||||
TheMem = MemoryManager.Instance.Allocate(memInfo.Preferred)
|
||||
};
|
||||
|
||||
var xrc = ReturnCode.Success;
|
||||
do
|
||||
{
|
||||
xrc = DGImage.ImageMemFileXfer.Get(xferInfo);
|
||||
|
||||
if (xrc == ReturnCode.Success ||
|
||||
xrc == ReturnCode.XferDone)
|
||||
{
|
||||
State = 7;
|
||||
byte[] buffer = new byte[(int)xferInfo.BytesWritten];
|
||||
// todo: need lock before use?
|
||||
IntPtr lockPtr = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
lockPtr = MemoryManager.Instance.Lock(xferInfo.Memory.TheMem);
|
||||
Marshal.Copy(lockPtr, buffer, 0, buffer.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockPtr != IntPtr.Zero)
|
||||
{
|
||||
MemoryManager.Instance.Unlock(lockPtr);
|
||||
}
|
||||
}
|
||||
// now what?
|
||||
|
||||
}
|
||||
} while (xrc == ReturnCode.Success);
|
||||
|
||||
if (xrc == ReturnCode.XferDone)
|
||||
{
|
||||
TWImageInfo imgInfo;
|
||||
//TWExtImageInfo extInfo;
|
||||
//if (SupportedCaps.Contains(CapabilityId.ICapExtImageInfo))
|
||||
//{
|
||||
// if (DGImage.ExtImageInfo.Get(out extInfo) != ReturnCode.Success)
|
||||
// {
|
||||
// extInfo = null;
|
||||
// }
|
||||
//}
|
||||
if (DGImage.ImageInfo.Get(out imgInfo) == ReturnCode.Success)
|
||||
{
|
||||
//OnDataTransferred(new DataTransferredEventArgs(IntPtr.Zero, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.TraceError("Failed to get image info after ImageMemXfer.");
|
||||
imgInfo = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
State = 6;
|
||||
if (xferInfo.Memory.TheMem != IntPtr.Zero)
|
||||
{
|
||||
MemoryManager.Instance.Free(xferInfo.Memory.TheMem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void DoImageMemoryFileXfer()
|
||||
@ -886,6 +973,7 @@ namespace NTwain
|
||||
{
|
||||
xferInfo.Memory = new TWMemory
|
||||
{
|
||||
Flags = MemoryFlags.AppOwns | MemoryFlags.Pointer,
|
||||
Length = memInfo.Preferred,
|
||||
TheMem = MemoryManager.Instance.Allocate(memInfo.Preferred)
|
||||
};
|
||||
@ -900,8 +988,22 @@ namespace NTwain
|
||||
if (xrc == ReturnCode.Success ||
|
||||
xrc == ReturnCode.XferDone)
|
||||
{
|
||||
State = 7;
|
||||
byte[] buffer = new byte[(int)xferInfo.BytesWritten];
|
||||
Marshal.Copy(xferInfo.Memory.TheMem, buffer, 0, buffer.Length);
|
||||
// todo: need lock before use?
|
||||
IntPtr lockPtr = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
lockPtr = MemoryManager.Instance.Lock(xferInfo.Memory.TheMem);
|
||||
Marshal.Copy(lockPtr, buffer, 0, buffer.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockPtr != IntPtr.Zero)
|
||||
{
|
||||
MemoryManager.Instance.Unlock(lockPtr);
|
||||
}
|
||||
}
|
||||
outStream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
} while (xrc == ReturnCode.Success);
|
||||
@ -962,6 +1064,7 @@ namespace NTwain
|
||||
}
|
||||
finally
|
||||
{
|
||||
State = 6;
|
||||
if (xferInfo.Memory.TheMem != IntPtr.Zero)
|
||||
{
|
||||
MemoryManager.Instance.Free(xferInfo.Memory.TheMem);
|
||||
@ -974,7 +1077,12 @@ namespace NTwain
|
||||
|
||||
if (File.Exists(finalFile))
|
||||
{
|
||||
OnDataTransferred(new DataTransferredEventArgs(IntPtr.Zero, finalFile));
|
||||
TWImageInfo imgInfo;
|
||||
if (DGImage.ImageInfo.Get(out imgInfo) != ReturnCode.Success)
|
||||
{
|
||||
imgInfo = null;
|
||||
}
|
||||
OnDataTransferred(new DataTransferredEventArgs { FilePath = finalFile, FinalImageInfo = imgInfo });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ namespace NTwain
|
||||
{
|
||||
lockedPtr = MemoryManager.Instance.Lock(dataPtr);
|
||||
}
|
||||
OnDataTransferred(new DataTransferredEventArgs(lockedPtr, file));
|
||||
OnDataTransferred(new DataTransferredEventArgs { NativeData = lockedPtr, FilePath = file });
|
||||
}
|
||||
//}
|
||||
//else if (group == DataGroups.Audio)
|
||||
|
@ -1,26 +0,0 @@
|
||||
using NTwain;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using NTwain.Values;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace NTwain.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class DataTransferredEventArgsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void Constructor_Sets_Correct_Properties()
|
||||
{
|
||||
// just some non-default values to test
|
||||
IntPtr data = new IntPtr(10);
|
||||
string file = "THIS IS A TEST.";
|
||||
|
||||
DataTransferredEventArgs target = new DataTransferredEventArgs(data, file);
|
||||
|
||||
Assert.AreEqual(data, target.Data, "Data mismatch.");
|
||||
Assert.AreEqual(file, target.FilePath, "File mismatch.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -54,9 +54,6 @@
|
||||
</CodeAnalysisDependentAssemblyPaths>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DataTransferredEventArgsTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Data\TWIdentityTest.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
@ -93,7 +93,7 @@ namespace Tester
|
||||
|
||||
static void twain_DataTransferred(object sender, DataTransferredEventArgs e)
|
||||
{
|
||||
if (e.Data != IntPtr.Zero)
|
||||
if (e.NativeData != IntPtr.Zero)
|
||||
{
|
||||
Console.WriteLine("Got twain data on thread {0}", Thread.CurrentThread.ManagedThreadId);
|
||||
}
|
||||
|
@ -63,9 +63,9 @@ namespace Tester.WPF
|
||||
|
||||
protected override void OnDataTransferred(DataTransferredEventArgs e)
|
||||
{
|
||||
if (e.Data != IntPtr.Zero)
|
||||
if (e.NativeData != IntPtr.Zero)
|
||||
{
|
||||
Image = e.Data.GetWPFBitmap();
|
||||
Image = e.NativeData.GetWPFBitmap();
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(e.FilePath))
|
||||
{
|
||||
|
@ -69,10 +69,10 @@ namespace Tester.Winform
|
||||
pictureBox1.Image.Dispose();
|
||||
pictureBox1.Image = null;
|
||||
}
|
||||
if (e.Data != IntPtr.Zero)
|
||||
if (e.NativeData != IntPtr.Zero)
|
||||
{
|
||||
//_ptrTest = e.Data;
|
||||
var img = e.Data.GetDrawingBitmap();
|
||||
var img = e.NativeData.GetDrawingBitmap();
|
||||
if (img != null)
|
||||
pictureBox1.Image = img;
|
||||
}
|
||||
@ -284,7 +284,7 @@ namespace Tester.Winform
|
||||
{
|
||||
var list = _twain.CapGetSupportedSizes();
|
||||
comboSize.DataSource = list;
|
||||
var cur = _twain.GetCurrentCap<SupportedSize>(CapabilityId.ICapSupportedSizes);
|
||||
var cur = _twain.GetCurrentCap(CapabilityId.ICapSupportedSizes).ConvertToEnum<SupportedSize>();
|
||||
if (list.Contains(cur))
|
||||
{
|
||||
comboSize.SelectedItem = cur;
|
||||
@ -293,7 +293,7 @@ namespace Tester.Winform
|
||||
|
||||
private void LoadDuplex()
|
||||
{
|
||||
ckDuplex.Checked = _twain.GetCurrentCap<uint>(CapabilityId.CapDuplexEnabled) != 0;
|
||||
ckDuplex.Checked = _twain.GetCurrentCap(CapabilityId.CapDuplexEnabled).ConvertToEnum<uint>() != 0;
|
||||
}
|
||||
|
||||
private void LoadDPI()
|
||||
@ -301,7 +301,7 @@ namespace Tester.Winform
|
||||
// only allow dpi of certain values for those source that lists everything
|
||||
var list = _twain.CapGetDPIs().Where(dpi => (dpi % 50) == 0).ToList();
|
||||
comboDPI.DataSource = list;
|
||||
var cur = _twain.GetCurrentCap<int>(CapabilityId.ICapXResolution);
|
||||
var cur = (TWFix32)_twain.GetCurrentCap(CapabilityId.ICapXResolution);
|
||||
if (list.Contains(cur))
|
||||
{
|
||||
comboDPI.SelectedItem = cur;
|
||||
@ -312,7 +312,7 @@ namespace Tester.Winform
|
||||
{
|
||||
var list = _twain.CapGetPixelTypes();
|
||||
comboDepth.DataSource = list;
|
||||
var cur = _twain.GetCurrentCap<PixelType>(CapabilityId.ICapPixelType);
|
||||
var cur = _twain.GetCurrentCap(CapabilityId.ICapPixelType).ConvertToEnum<PixelType>();
|
||||
if (list.Contains(cur))
|
||||
{
|
||||
comboDepth.SelectedItem = cur;
|
||||
|
Loading…
Reference in New Issue
Block a user